oneis 1.0.0-java
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.
- data/README.txt +19 -0
- data/bin/oneis-plugin +37 -0
- data/lib/CertificateBundle.pem +1019 -0
- data/lib/check.rb +58 -0
- data/lib/hmac.rb +12 -0
- data/lib/js.jar +0 -0
- data/lib/js_min.js +38 -0
- data/lib/js_syntax_test.js +81 -0
- data/lib/jshint.js +4359 -0
- data/lib/manifest.rb +41 -0
- data/lib/minimise.rb +68 -0
- data/lib/misc.rb +8 -0
- data/lib/new_plugin.rb +91 -0
- data/lib/notifications.rb +69 -0
- data/lib/packing.rb +59 -0
- data/lib/plugin.rb +207 -0
- data/lib/plugin_tool.rb +159 -0
- data/lib/server.rb +131 -0
- data/lib/syntax_checking.rb +87 -0
- data/lib/uglifyjs/parse-js.js +1342 -0
- data/lib/uglifyjs/process.js +2011 -0
- data/lib/uglifyjs/squeeze-more.js +69 -0
- data/lib/usage.txt +72 -0
- data/lib/version.txt +1 -0
- data/lib/watchers.rb +39 -0
- data/oneis.gemspec +19 -0
- metadata +100 -0
data/lib/manifest.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
module PluginTool
|
3
|
+
|
4
|
+
ALLOWED_PLUGIN_DIRS = ['js', 'static', 'template', 'test', 'data']
|
5
|
+
|
6
|
+
def self.generate_manifest(directory)
|
7
|
+
manifest = Hash.new
|
8
|
+
Dir.glob("#{directory}/**/*").sort.each do |pathname|
|
9
|
+
# Ignore directories
|
10
|
+
next unless File.file? pathname
|
11
|
+
# Check file
|
12
|
+
filename = pathname.slice(directory.length + 1, pathname.length)
|
13
|
+
raise "Bad filename for #{filename}" unless filename =~ /\A([a-zA-Z0-9_\/\-]+\/)?([a-z0-9_-]+\.[a-z0-9]+)\Z/
|
14
|
+
dir = $1
|
15
|
+
name = $2
|
16
|
+
if dir != nil
|
17
|
+
dir = dir.gsub(/\/\Z/,'')
|
18
|
+
raise "Bad directory #{dir}" unless dir =~ /\A([a-zA-Z0-9_\-]+)[a-zA-Z0-9_\/\-]*\Z/
|
19
|
+
raise "Bad root directory #{$1}" unless ALLOWED_PLUGIN_DIRS.include?($1)
|
20
|
+
end
|
21
|
+
# Get hash of file
|
22
|
+
digest = File.open(pathname) { |f| Digest::SHA1.hexdigest(f.read) }
|
23
|
+
# And add to manifest
|
24
|
+
manifest[filename] = digest
|
25
|
+
end
|
26
|
+
manifest
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.determine_manifest_changes(from, to)
|
30
|
+
changes = []
|
31
|
+
from.each_key do |name|
|
32
|
+
changes << [name, :delete] unless to.has_key?(name)
|
33
|
+
end
|
34
|
+
to.each do |name,hash|
|
35
|
+
changes << [name, hash] unless from[name] == hash
|
36
|
+
end
|
37
|
+
changes
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
data/lib/minimise.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
module PluginTool
|
3
|
+
|
4
|
+
class Minimiser
|
5
|
+
Context = Java::OrgMozillaJavascript::Context
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
# Load UglifyJS into a JavaScript interpreter
|
9
|
+
raise "Another JS Context is active" unless nil == Context.getCurrentContext()
|
10
|
+
@cx = Context.enter();
|
11
|
+
@cx.setLanguageVersion(Context::VERSION_1_7)
|
12
|
+
@javascript_scope = @cx.initStandardObjects()
|
13
|
+
['js_min.js','uglifyjs/parse-js.js','uglifyjs/process.js','uglifyjs/squeeze-more.js'].each do |filename|
|
14
|
+
js = File.open("#{File.dirname(__FILE__)}/#{filename}") { |f| f.read }
|
15
|
+
@cx.evaluateString(@javascript_scope, js, "<#{filename}>", 1, nil);
|
16
|
+
end
|
17
|
+
@js_min = @javascript_scope.get("js_min", @javascript_scope);
|
18
|
+
end
|
19
|
+
|
20
|
+
def process(data, filename)
|
21
|
+
if filename =~ /\.js\Z/
|
22
|
+
# JavaScript - use UglifyJS loaded into the JavaScript interpreter
|
23
|
+
@js_min.call(@cx, @javascript_scope, @javascript_scope, [data])
|
24
|
+
|
25
|
+
elsif filename =~ /\.html\Z/
|
26
|
+
# Simple processing of HTML
|
27
|
+
# Remove HTML comments
|
28
|
+
html = data.gsub(/\<\!\-\-.+?\-\-\>/m,'')
|
29
|
+
# Remove indents
|
30
|
+
html.gsub!(/^\s+/,'')
|
31
|
+
# Remove any unnecessary line breaks (fairly conservative)
|
32
|
+
html.gsub!(/\>[\r\n]+\</m,'><')
|
33
|
+
html.gsub!(/([\>}])[\r\n]+([\<{])/m,'\1\2')
|
34
|
+
html
|
35
|
+
|
36
|
+
elsif filename =~ /\.css\Z/
|
37
|
+
# Simple processing of CSS
|
38
|
+
css = data.gsub(/(^|\s)\/\*.+?\*\/($|\s)/m,'') # remove C style comments
|
39
|
+
out = []
|
40
|
+
css.split(/[\r\n]+/).each do |line|
|
41
|
+
line.chomp!; line.gsub!(/^\s+/,''); line.gsub!(/\s+$/,'')
|
42
|
+
line.gsub!(/\s+/,' ') # contract spaces
|
43
|
+
line.gsub!(/\s*:\s*/,':') # remove unnecessary spaces
|
44
|
+
if line =~ /\S/
|
45
|
+
out << line
|
46
|
+
end
|
47
|
+
end
|
48
|
+
css = out.join("\n")
|
49
|
+
# Remove unnecessary line endings
|
50
|
+
css.gsub!(/[\r\n]*(\{[^\}]+\})/m) do |m|
|
51
|
+
$1.gsub(/[\r\n]/m,'')
|
52
|
+
end
|
53
|
+
css
|
54
|
+
|
55
|
+
else
|
56
|
+
# No processing
|
57
|
+
data
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def finish
|
62
|
+
Context.exit()
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
data/lib/misc.rb
ADDED
data/lib/new_plugin.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
|
2
|
+
module PluginTool
|
3
|
+
|
4
|
+
def self.make_new_plugin(plugin_name)
|
5
|
+
unless plugin_name =~ /\A[a-z0-9_]+\Z/ && plugin_name.length > 8
|
6
|
+
end_on_error "Bad plugin name - must use a-z0-9_ only, and more than 8 characters."
|
7
|
+
end
|
8
|
+
if File.exist?(plugin_name)
|
9
|
+
end_on_error "File or directory #{plugin_name} already exists"
|
10
|
+
end
|
11
|
+
FileUtils.mkdir(plugin_name)
|
12
|
+
['js', 'static', 'template', 'test'].each do |dir|
|
13
|
+
FileUtils.mkdir("#{plugin_name}/#{dir}")
|
14
|
+
end
|
15
|
+
random = java.security.SecureRandom.new()
|
16
|
+
rbytes = Java::byte[20].new
|
17
|
+
random.nextBytes(rbytes)
|
18
|
+
install_secret = String.from_java_bytes(rbytes).unpack('H*').join
|
19
|
+
File.open("#{plugin_name}/plugin.json",'w') do |file|
|
20
|
+
file.write(<<__E)
|
21
|
+
{
|
22
|
+
"pluginName": "#{plugin_name}",
|
23
|
+
"pluginAuthor": "TODO Your Company",
|
24
|
+
"pluginVersion": 1,
|
25
|
+
"displayName": "#{plugin_name.split('_').map {|e| e.capitalize} .join(' ')}",
|
26
|
+
"displayDescription": "TODO Longer description of plugin",
|
27
|
+
"installSecret": "#{install_secret}",
|
28
|
+
"apiVersion": 0,
|
29
|
+
"load": ["js/#{plugin_name}.js"],
|
30
|
+
"respond": ["/do/#{plugin_name}"]
|
31
|
+
}
|
32
|
+
__E
|
33
|
+
end
|
34
|
+
File.open("#{plugin_name}/js/#{plugin_name}.js",'w') do |file|
|
35
|
+
file.write(<<__E)
|
36
|
+
|
37
|
+
var #{plugin_name} = O.plugin("#{plugin_name}", {
|
38
|
+
});
|
39
|
+
|
40
|
+
(function() {
|
41
|
+
|
42
|
+
#{plugin_name}.respond("GET", "/do/#{plugin_name}/example", [
|
43
|
+
], function(E) {
|
44
|
+
E.render({
|
45
|
+
pageTitle: "Example page"
|
46
|
+
});
|
47
|
+
});
|
48
|
+
|
49
|
+
})();
|
50
|
+
|
51
|
+
__E
|
52
|
+
end
|
53
|
+
File.open("#{plugin_name}/template/example.html",'w') do |file|
|
54
|
+
file.write(<<__E)
|
55
|
+
<p>This is an example template.</p>
|
56
|
+
__E
|
57
|
+
end
|
58
|
+
File.open("#{plugin_name}/test/#{plugin_name}_test1.js",'w') do |file|
|
59
|
+
file.write(<<__E)
|
60
|
+
|
61
|
+
T.test(function() {
|
62
|
+
|
63
|
+
// For documentation, see
|
64
|
+
// http://docs.oneis.co.uk/dev/plugin/tests
|
65
|
+
|
66
|
+
T.assert(true);
|
67
|
+
|
68
|
+
});
|
69
|
+
|
70
|
+
__E
|
71
|
+
end
|
72
|
+
puts <<__E
|
73
|
+
|
74
|
+
Plugin #{plugin_name} has been created. Run
|
75
|
+
|
76
|
+
oneis-plugin -p #{plugin_name}
|
77
|
+
|
78
|
+
to upload it to the server, then visit
|
79
|
+
|
80
|
+
https://<HOSTNAME>/do/#{plugin_name}/example
|
81
|
+
|
82
|
+
to see a sample page.
|
83
|
+
|
84
|
+
Add additional hook handlers in the js/#{plugin_name}.js file.
|
85
|
+
|
86
|
+
See http://docs.oneis.co.uk/dev/plugin for more information.
|
87
|
+
|
88
|
+
__E
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
module PluginTool
|
3
|
+
|
4
|
+
@@notification_announce_reconnect = false
|
5
|
+
|
6
|
+
def self.start_notifications
|
7
|
+
@@notification_queue_name = nil
|
8
|
+
Thread.new do
|
9
|
+
while true
|
10
|
+
begin
|
11
|
+
self.do_notifications
|
12
|
+
rescue => e
|
13
|
+
puts "NOTICE: Lost notification connection, will attempt to reconnect soon."
|
14
|
+
@@notification_announce_reconnect = true
|
15
|
+
sleep(5) # throttle errors
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.do_notifications
|
22
|
+
http = make_http_connection
|
23
|
+
puts "NOTICE: Notification connection established." if @@notification_announce_reconnect
|
24
|
+
while true
|
25
|
+
sleep(0.25) # small throttle of requests
|
26
|
+
path = '/api/development_plugin_loader/get_notifications'
|
27
|
+
path << "?queue=#{@@notification_queue_name}" if @@notification_queue_name
|
28
|
+
request = Net::HTTP::Get.new(path)
|
29
|
+
setup_request(request)
|
30
|
+
# Server uses long-polling, and will respond after a long timeout, or when a notification
|
31
|
+
# has been queued for sending to this process.
|
32
|
+
response = http.request(request)
|
33
|
+
if response.kind_of?(Net::HTTPOK)
|
34
|
+
@@notification_queue_name = response['X-Queue-Name']
|
35
|
+
begin
|
36
|
+
decode_and_handle_notifications response.body
|
37
|
+
rescue
|
38
|
+
puts "NOTICE: Error handling notification from server."
|
39
|
+
end
|
40
|
+
else
|
41
|
+
raise "Bad response"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.decode_and_handle_notifications(encoded)
|
47
|
+
size = encoded.length
|
48
|
+
pos = 0
|
49
|
+
while pos < (size - 12)
|
50
|
+
type = encoded[pos, 4]
|
51
|
+
data_size = encoded[pos + 4, 8].to_i(16)
|
52
|
+
data = encoded[pos + 12, data_size]
|
53
|
+
pos += 12 + data_size
|
54
|
+
handle_notification(type, data)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.handle_notification(type, data)
|
59
|
+
case type
|
60
|
+
when 'log '
|
61
|
+
# Output from console.log()
|
62
|
+
puts "LOG:#{data}"
|
63
|
+
else
|
64
|
+
puts "WARNING: Unknown notification received from server. Upgrade the plugin tool."
|
65
|
+
sleep(5) # throttle problematic responses
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/lib/packing.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
|
2
|
+
module PluginTool
|
3
|
+
|
4
|
+
PACKING_ACCEPTABLE_FILENAME = /\A(plugin\.json|(js|static|template)\/[a-z0-9_-]+\.[a-z0-9]+)\Z/
|
5
|
+
PACKING_ACCEPTABLE_EXCEPTIONS = ['certificates-temp-http-api.pem']
|
6
|
+
|
7
|
+
def self.pack_plugin(plugin_name, output_directory)
|
8
|
+
# Get filenames and sort
|
9
|
+
files = Dir.glob("#{plugin_name}/**/*").map do |filename|
|
10
|
+
if File.file? filename
|
11
|
+
filename[plugin_name.length+1, filename.length]
|
12
|
+
else
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
end .compact.sort
|
16
|
+
# Check each filename is acceptable
|
17
|
+
files.each do |filename|
|
18
|
+
unless filename =~ PACKING_ACCEPTABLE_FILENAME || PACKING_ACCEPTABLE_EXCEPTIONS.include?(filename)
|
19
|
+
puts "File '#{filename}' has an unacceptable filename"
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
# Clean output directory
|
24
|
+
output_plugin_dir = "#{output_directory}/#{plugin_name}"
|
25
|
+
puts "Output directory: #{output_plugin_dir}"
|
26
|
+
if File.exist? output_plugin_dir
|
27
|
+
puts "Removing old output directory #{output_plugin_dir}"
|
28
|
+
FileUtils.rm_r(output_plugin_dir)
|
29
|
+
end
|
30
|
+
# Make file structure
|
31
|
+
FileUtils.mkdir(output_plugin_dir)
|
32
|
+
['js','static','template'].each do |subdir|
|
33
|
+
FileUtils.mkdir("#{output_plugin_dir}/#{subdir}")
|
34
|
+
end
|
35
|
+
# Process each file, building a manifest
|
36
|
+
puts "Processing files:"
|
37
|
+
manifest = ''
|
38
|
+
minimiser = PluginTool::Minimiser.new
|
39
|
+
files.each do |filename|
|
40
|
+
puts " #{filename}"
|
41
|
+
data = File.open("#{plugin_name}/#{filename}") { |f| f.read }
|
42
|
+
# Minimise file?
|
43
|
+
unless filename =~ /\Ajs\//
|
44
|
+
data = minimiser.process(data, filename)
|
45
|
+
end
|
46
|
+
hash = Digest::SHA1.hexdigest(data)
|
47
|
+
File.open("#{output_plugin_dir}/#{filename}", "w") { |f| f.write data }
|
48
|
+
manifest << "F #{hash} #{filename}\n"
|
49
|
+
end
|
50
|
+
minimiser.finish
|
51
|
+
# Write manifest and version
|
52
|
+
File.open("#{output_plugin_dir}/manifest", "w") { |f| f.write manifest }
|
53
|
+
version = Digest::SHA1.hexdigest(manifest)
|
54
|
+
File.open("#{output_plugin_dir}/version", "w") { |f| f.write "#{version}\n" }
|
55
|
+
# All done
|
56
|
+
puts "Version: #{version}\nPlugin packed."
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/lib/plugin.rb
ADDED
@@ -0,0 +1,207 @@
|
|
1
|
+
|
2
|
+
module PluginTool
|
3
|
+
|
4
|
+
class Plugin
|
5
|
+
def initialize(name, options)
|
6
|
+
@name = name
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
attr_accessor :name
|
10
|
+
attr_accessor :plugin_dir
|
11
|
+
|
12
|
+
# ---------------------------------------------------------------------------------------------------------
|
13
|
+
|
14
|
+
def start
|
15
|
+
# Check to see if the plugin is valid
|
16
|
+
unless File.file?("#{@name}/plugin.json")
|
17
|
+
end_on_error "Plugin #{@name} does not exist (no plugin.json file)"
|
18
|
+
end
|
19
|
+
# Setup for using the plugin
|
20
|
+
@plugin_dir = @name
|
21
|
+
end_on_error "logic error" unless @plugin_dir =~ /\A[a-zA-Z0-9_-]+\Z/
|
22
|
+
@registration_file = "registration.#{@plugin_dir}.yaml"
|
23
|
+
puts "Plugin: #{@plugin_dir}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def setup_for_server
|
27
|
+
# Make the first empty manifest (may be replaced from server)
|
28
|
+
@current_manifest = {}
|
29
|
+
|
30
|
+
# Get info about the current plugin
|
31
|
+
@loaded_plugin_id = nil
|
32
|
+
if File.exists? @registration_file
|
33
|
+
reg_info = YAML::load(File.open(@registration_file) { |f| f.read })
|
34
|
+
@loaded_plugin_id = reg_info[:plugin_id]
|
35
|
+
if @loaded_plugin_id != nil
|
36
|
+
# Check with server to see if this is still registered, and if so, what files it has on the server
|
37
|
+
s_reg_info = PluginTool.get_yaml("/api/development_plugin_loader/manifest/#{@loaded_plugin_id}")
|
38
|
+
end_on_error "Couldn't communicate successfully with server." if s_reg_info[:protocol_error]
|
39
|
+
if s_reg_info[:result] == 'success'
|
40
|
+
@current_manifest = s_reg_info[:manifest]
|
41
|
+
else
|
42
|
+
puts "NOTICE: Discarding registration information from #{@registration_file}"
|
43
|
+
@loaded_plugin_id = nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# If minimisation is active, clear the current manifest so all files are uploaded again.
|
49
|
+
if @options.minimiser != nil
|
50
|
+
@current_manifest = {}
|
51
|
+
end
|
52
|
+
|
53
|
+
# Flag for registration file save
|
54
|
+
registration_file_needs_update = false
|
55
|
+
|
56
|
+
# If the current plugin registration isn't known, see if the server knows about it
|
57
|
+
if @loaded_plugin_id == nil
|
58
|
+
s_found_info = PluginTool.post_yaml("/api/development_plugin_loader/find_registration", {:name => @name})
|
59
|
+
if s_found_info[:found]
|
60
|
+
# Store info returned by the server
|
61
|
+
puts "NOTICE: Found existing registration for #{@name} on server. Using it."
|
62
|
+
@loaded_plugin_id = s_found_info[:plugin_id]
|
63
|
+
@current_manifest = s_found_info[:manifest]
|
64
|
+
registration_file_needs_update = true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# If there isn't an existing plugin registered, create a new one
|
69
|
+
if @loaded_plugin_id == nil
|
70
|
+
s_create_info = PluginTool.post_yaml("/api/development_plugin_loader/create")
|
71
|
+
end_on_error "Couldn't communicate successfully with server." if s_create_info[:protocol_error]
|
72
|
+
end_on_error "Failed to create plugin on server" unless s_create_info[:plugin_id] != nil
|
73
|
+
@loaded_plugin_id = s_create_info[:plugin_id]
|
74
|
+
registration_file_needs_update = true
|
75
|
+
end
|
76
|
+
|
77
|
+
# Update registration file for next run?
|
78
|
+
if registration_file_needs_update
|
79
|
+
File.open(@registration_file, 'w') { |f| f.write YAML::dump(:plugin_id => @loaded_plugin_id) }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# ---------------------------------------------------------------------------------------------------------
|
84
|
+
|
85
|
+
def command(cmd)
|
86
|
+
case cmd
|
87
|
+
when 'license-key'
|
88
|
+
application_id = @options.args.first
|
89
|
+
if application_id == nil || application_id !~ /\A\d+\Z/
|
90
|
+
end_on_error "Numeric application ID must be specified"
|
91
|
+
end
|
92
|
+
generate_license_key(application_id)
|
93
|
+
|
94
|
+
when 'pack'
|
95
|
+
PluginTool.pack_plugin(@name, @options.output)
|
96
|
+
|
97
|
+
when 'reset-db'
|
98
|
+
puts "Resetting database on server for #{@name}..."
|
99
|
+
reset_result = PluginTool.post_yaml("/api/development_plugin_loader/resetdb/#{@loaded_plugin_id}")
|
100
|
+
end_on_error "Couldn't remove old database tables" unless reset_result[:result] == 'success'
|
101
|
+
apply_result = PluginTool.get_yaml("/api/development_plugin_loader/apply/#{@loaded_plugin_id}")
|
102
|
+
end_on_error "Couldn't apply changes" unless apply_result[:result] == 'success'
|
103
|
+
puts "Done."
|
104
|
+
|
105
|
+
when 'uninstall'
|
106
|
+
puts "Uninstalling plugin #{@name} from server..."
|
107
|
+
reset_result = PluginTool.post_yaml("/api/development_plugin_loader/uninstall/#{@loaded_plugin_id}")
|
108
|
+
end_on_error "Couldn't uninstall plugin" unless reset_result[:result] == 'success'
|
109
|
+
puts "Done."
|
110
|
+
|
111
|
+
when 'test'
|
112
|
+
puts "Running tests..."
|
113
|
+
params = {}
|
114
|
+
params[:test] = @options.args.first unless @options.args.empty?
|
115
|
+
test_result = PluginTool.post_yaml("/api/development_plugin_loader/run_tests/#{@loaded_plugin_id}", params)
|
116
|
+
end_on_error "Couldn't run tests" unless test_result[:result] == 'success'
|
117
|
+
puts
|
118
|
+
puts test_result[:output] || ''
|
119
|
+
puts test_result[:summary] || "(unknown results)"
|
120
|
+
|
121
|
+
when 'develop'
|
122
|
+
# do nothing here
|
123
|
+
|
124
|
+
else
|
125
|
+
end_on_error "Unknown command '#{cmd}'"
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# ---------------------------------------------------------------------------------------------------------
|
131
|
+
|
132
|
+
def develop_setup
|
133
|
+
end
|
134
|
+
|
135
|
+
def develop_scan_and_upload(first_run)
|
136
|
+
next_manifest = PluginTool.generate_manifest(@plugin_dir)
|
137
|
+
changes = PluginTool.determine_manifest_changes(@current_manifest, next_manifest)
|
138
|
+
upload_failed = false
|
139
|
+
changes.each do |filename, action|
|
140
|
+
filename =~ /\A(.*?\/)?([^\/]+)\Z/
|
141
|
+
params = {:filename => $2}
|
142
|
+
params[:directory] = $1.gsub(/\/\Z/,'') if $1
|
143
|
+
if action == :delete
|
144
|
+
puts " #{@name}: Deleting #{filename}"
|
145
|
+
PluginTool.post_yaml("/api/development_plugin_loader/delete_file/#{@loaded_plugin_id}", params)
|
146
|
+
else
|
147
|
+
puts " #{@name}: Uploading #{filename}"
|
148
|
+
data = File.open("#{@plugin_dir}/#{filename}") { |f| f.read }
|
149
|
+
hash = action
|
150
|
+
# Minimise file before uploading?
|
151
|
+
if @options.minimiser != nil && filename =~ /\A(static|template)\//
|
152
|
+
size_before = data.length
|
153
|
+
data = @options.minimiser.process(data, filename)
|
154
|
+
size_after = data.length
|
155
|
+
hash = Digest::SHA1.hexdigest(data)
|
156
|
+
puts " minimisation: #{size_before} -> #{size_after} (#{(size_after * 100) / size_before}%)"
|
157
|
+
end
|
158
|
+
r = PluginTool.post_yaml("/api/development_plugin_loader/put_file/#{@loaded_plugin_id}", params, {:file => [filename, data]})
|
159
|
+
if r[:result] == 'success'
|
160
|
+
# If the file was uploaded successfully, but the hash didn't match, abort now
|
161
|
+
end_on_error "#{@name}: Disagreed with server about uploaded file hash: local=#{hash}, remote=#{r[:hash]}" unless hash == r[:hash]
|
162
|
+
else
|
163
|
+
# Otherwise mark as a failed upload to stop an apply operation which will fail
|
164
|
+
upload_failed = true
|
165
|
+
end
|
166
|
+
PluginTool.syntax_check(self, filename) if filename =~ /\.js\Z/
|
167
|
+
end
|
168
|
+
end
|
169
|
+
if upload_failed
|
170
|
+
puts "\n#{@name}: Not applying changes due to failure\n\n"
|
171
|
+
else
|
172
|
+
if !(changes.empty?) || first_run
|
173
|
+
puts " #{@name}: Applying changes on server"
|
174
|
+
r = PluginTool.get_yaml("/api/development_plugin_loader/apply/#{@loaded_plugin_id}")
|
175
|
+
unless r[:result] == 'success'
|
176
|
+
puts "\n\n#{@name}: Didn't apply changes on server\n\n"
|
177
|
+
PluginTool.beep
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
PluginTool.finish_with_connection
|
182
|
+
@current_manifest = next_manifest
|
183
|
+
end
|
184
|
+
|
185
|
+
# ---------------------------------------------------------------------------------------------------------
|
186
|
+
|
187
|
+
def generate_license_key(application_id)
|
188
|
+
info = File.open("#{@plugin_dir}/plugin.json") { |f| JSON.parse(f.read) }
|
189
|
+
if info["installSecret"] == nil
|
190
|
+
end_on_error "#{@name}: No installSecret specified in plugin.json"
|
191
|
+
end
|
192
|
+
license_key = HMAC::SHA1.sign(info["installSecret"], "application:#{ARGV[1]}")
|
193
|
+
puts <<__E
|
194
|
+
|
195
|
+
Plugin: #{@name}
|
196
|
+
Application: #{application_id}
|
197
|
+
License key: #{license_key}
|
198
|
+
__E
|
199
|
+
end
|
200
|
+
|
201
|
+
def end_on_error(err)
|
202
|
+
puts err
|
203
|
+
exit 1
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|