oneis 1.0.0-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|