adobe_crx 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.
- data/bin/crx +4 -0
- data/lib/adobe_crx/cli/export.rb +29 -0
- data/lib/adobe_crx/cli/export_uber.rb +27 -0
- data/lib/adobe_crx/cli/generate_uber_manifest.rb +47 -0
- data/lib/adobe_crx/cli/import.rb +18 -0
- data/lib/adobe_crx/cli/import_uber.rb +27 -0
- data/lib/adobe_crx/cli.rb +36 -0
- data/lib/adobe_crx/client.rb +228 -0
- data/lib/adobe_crx/node.rb +21 -0
- data/lib/adobe_crx/package.rb +16 -0
- data/lib/adobe_crx/package_filter.rb +15 -0
- data/lib/adobe_crx/package_filter_rule.rb +15 -0
- data/lib/adobe_crx/package_utils.rb +15 -0
- data/lib/adobe_crx/uber_package.rb +32 -0
- data/lib/adobe_crx/uber_package_manager.rb +121 -0
- data/lib/adobe_crx/version.rb +1 -0
- data/lib/adobe_crx.rb +14 -0
- metadata +121 -0
data/bin/crx
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
command :export do |c|
|
2
|
+
c.syntax = 'crx export [options] <root path>'
|
3
|
+
c.description = 'Exports a simple package for the given root path'
|
4
|
+
c.option "--output_file OUTPUT_FILE", String, "package output file"
|
5
|
+
c.action do |args, options|
|
6
|
+
if !args[0]
|
7
|
+
say_error "no root path specified. Use --help for more information"
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
validate_global_options c, options
|
11
|
+
output_file = options.output_file
|
12
|
+
if output_file
|
13
|
+
if File.exists? output_file
|
14
|
+
overwrite = ask("File #{output_file} exists. Overwrite? (Y/N)")
|
15
|
+
if overwrite == 'Y'
|
16
|
+
File.delete output_file
|
17
|
+
else
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
package = AdobeCRX::Package.new "export-#{Time.now.strftime('%Y%m%d%H%M%S')}-#{args[0]}".gsub('/', '-').gsub(' ', '_').gsub("%20", '_')
|
24
|
+
package.filters << AdobeCRX::PackageFilter.new(args[0])
|
25
|
+
|
26
|
+
client = AdobeCRX::Client.new options.host, options.port, options.username, options.password
|
27
|
+
client.export_package package, output_file
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
command :export_uber do |c|
|
2
|
+
c.syntax = 'crx export_uber [options] <uber manifest location>'
|
3
|
+
c.description = 'Exports an "uber" package based on a manifest file (see the generate_uber_manifest command).'
|
4
|
+
c.option "--output_dir OUTPUT_DIR", String, "uber package output directory"
|
5
|
+
c.action do |args, options|
|
6
|
+
if !args[0]
|
7
|
+
say_error "no uber manifest specified. Use --help for more information"
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
if !File.exist? args[0]
|
11
|
+
say_error "uber manifest file (#{args[0]}) does not exist"
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
validate_global_options c, options
|
15
|
+
output_dir = options.output_dir
|
16
|
+
if output_dir
|
17
|
+
if !File.writable? output_dir
|
18
|
+
say_error "unable to write to output directory #{output_dir}"
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
client = AdobeCRX::Client.new options.host, options.port, options.username, options.password
|
24
|
+
upm = AdobeCRX::UberPackageManager.new client
|
25
|
+
json = upm.export_uber_package args[0], output_dir
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
command :generate_uber_manifest do |c|
|
2
|
+
c.syntax = 'crx generate_uber_manifest [options] <root path>'
|
3
|
+
c.description = 'Generates an uber package manifest.'
|
4
|
+
c.option "--output_file OUTPUT_FILE", String, "uber manifest output file location"
|
5
|
+
c.option "--export_name EXPORT_NAME", String, "export name"
|
6
|
+
c.option "--root_package_depth ROOT_PACKAGE_DEPTH", String, "specify the node depth of the root package. defaults to '1'"
|
7
|
+
c.option "--target_package_size TARGET_PACKAGE_SIZE", String, "specify the desired size of 'leaf' packages. defaults to '0', which means to not check content size (results in faster manifest creation)"
|
8
|
+
c.action do |args, options|
|
9
|
+
if !args[0]
|
10
|
+
say_error "no root path specified. Use --help for more information"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
validate_global_options c, options
|
14
|
+
output_file = options.output_file
|
15
|
+
if output_file
|
16
|
+
if File.exists? output_file
|
17
|
+
overwrite = ask("File #{output_file} exists. Overwrite? (Y/N)")
|
18
|
+
if overwrite == 'Y'
|
19
|
+
File.delete output_file
|
20
|
+
else
|
21
|
+
exit 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
export_name = options.export_name
|
26
|
+
export_name = 'export' if !export_name
|
27
|
+
|
28
|
+
uber_options = {}
|
29
|
+
if options.root_package_depth
|
30
|
+
uber_options[:root_package_depth] = options.root_package_depth.to_i
|
31
|
+
end
|
32
|
+
if options.target_package_size
|
33
|
+
uber_options[:target_package_size] = options.target_package_size.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
client = AdobeCRX::Client.new options.host, options.port, options.username, options.password
|
37
|
+
upm = AdobeCRX::UberPackageManager.new client
|
38
|
+
json = upm.generate_uber_package_definition export_name, args[0], uber_options
|
39
|
+
if output_file
|
40
|
+
File.open output_file, 'w' do |f|
|
41
|
+
f.write(json)
|
42
|
+
end
|
43
|
+
else
|
44
|
+
puts json
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
command :import do |c|
|
2
|
+
c.syntax = 'crx import [options] <package file>'
|
3
|
+
c.description = 'Imports a package to the target crx instance'
|
4
|
+
c.action do |args, options|
|
5
|
+
if !args[0]
|
6
|
+
say_error "no package file specified. Use --help for more information"
|
7
|
+
exit 1
|
8
|
+
end
|
9
|
+
if !File.exist? args[0]
|
10
|
+
say_error "package file (#{args[0]}) does not exist"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
validate_global_options c, options
|
14
|
+
|
15
|
+
client = AdobeCRX::Client.new options.host, options.port, options.username, options.password
|
16
|
+
client.import_package args[0]
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
command :import_uber do |c|
|
2
|
+
c.syntax = 'crx import_uber [options] <uber package dir> [uber manifest file]'
|
3
|
+
c.description = 'Imports an "uber" package from a given directory (and optional manifest file--if not specified the manifest is assumed to be <uber package dir>/manifest.json).'
|
4
|
+
c.action do |args, options|
|
5
|
+
if !args[0]
|
6
|
+
say_error "no uber manifest directory. Use --help for more information"
|
7
|
+
exit 1
|
8
|
+
end
|
9
|
+
if !File.directory? args[0]
|
10
|
+
say_error "uber manifest directory (#{args[0]}) does not exist"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
manifest_file = args[1]
|
14
|
+
if !manifest_file
|
15
|
+
manifest_file = "#{args[0]}/manifest.json"
|
16
|
+
end
|
17
|
+
if !File.exist? manifest_file
|
18
|
+
say_error "uber manifest file (#{manifest_file}) does not exist"
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
validate_global_options c, options
|
22
|
+
|
23
|
+
client = AdobeCRX::Client.new options.host, options.port, options.username, options.password
|
24
|
+
upm = AdobeCRX::UberPackageManager.new client
|
25
|
+
upm.import_uber_package manifest_file, args[0]
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'commander/import'
|
3
|
+
require 'adobe_crx'
|
4
|
+
|
5
|
+
program :name, 'crx'
|
6
|
+
program :version, '0.0.1'
|
7
|
+
program :description, 'Command line tools for Adobe CRX.'
|
8
|
+
|
9
|
+
global_option "--host HOSTNAME", String, "crx HOSTNAME"
|
10
|
+
global_option "--port PORT", Float, "crx PORT"
|
11
|
+
global_option "--username USERNAME", String, "crx USERNAME"
|
12
|
+
global_option "--password PASSWORD", String, "crx PASSWORD"
|
13
|
+
|
14
|
+
def validate_global_options(command, options)
|
15
|
+
if !options.host
|
16
|
+
options.host = ask 'CRX host:'
|
17
|
+
end
|
18
|
+
if !options.port
|
19
|
+
options.port = ask 'CRX port:'
|
20
|
+
else
|
21
|
+
options.port = options.port.to_i
|
22
|
+
end
|
23
|
+
if !options.username
|
24
|
+
options.username = ask 'CRX username:'
|
25
|
+
end
|
26
|
+
if !options.password
|
27
|
+
options.password = password('CRX password:')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Dir.foreach(File.dirname(__FILE__) + '/cli') do |filename|
|
32
|
+
to_require = File.basename(filename, '.rb')
|
33
|
+
if !to_require.match(/^\./)
|
34
|
+
require "adobe_crx/cli/#{to_require}"
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rexml/document'
|
3
|
+
require 'net/http'
|
4
|
+
require 'net/http/post/multipart'
|
5
|
+
require 'net/dav'
|
6
|
+
require 'json'
|
7
|
+
require 'tmpdir'
|
8
|
+
|
9
|
+
# monkey-patch so that we can take advantage of the innards of Net::DAV
|
10
|
+
module Net
|
11
|
+
class DAV
|
12
|
+
class NetHttpHandler
|
13
|
+
alias_method :handle_request_original, :handle_request
|
14
|
+
|
15
|
+
def handle_request(req, headers, limit = MAX_REDIRECTS, &block)
|
16
|
+
if @user && @pass
|
17
|
+
req.basic_auth @user, @pass
|
18
|
+
end
|
19
|
+
handle_request_original(req, headers, limit, &block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def propfind_size(path)
|
24
|
+
headers = {'Depth' => 'infinity'}
|
25
|
+
body = '<?xml version="1.0" encoding="utf-8"?><DAV:propfind xmlns:DAV="DAV:"><DAV:prop><DAV:getcontentlength/></DAV:prop></DAV:propfind>'
|
26
|
+
res = @handler.request(:propfind, path, body, headers)
|
27
|
+
total_size = 0
|
28
|
+
xml = Nokogiri::XML.parse(res.body)
|
29
|
+
namespaces = {'x' => "DAV:"}
|
30
|
+
xml./('.//x:response', namespaces).each do |item|
|
31
|
+
begin
|
32
|
+
total_size = total_size + item.%(".//x:getcontentlength", namespaces).inner_text.to_i
|
33
|
+
rescue Exception
|
34
|
+
#nothing
|
35
|
+
end
|
36
|
+
end
|
37
|
+
total_size
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class AdobeCRX::Client
|
43
|
+
def initialize(host, port, username, password)
|
44
|
+
@host = host
|
45
|
+
@port = port
|
46
|
+
@username = username
|
47
|
+
@password = password
|
48
|
+
end
|
49
|
+
|
50
|
+
#package management methods
|
51
|
+
def list_packages
|
52
|
+
xml_data = Net::HTTP.get_response(URI.parse("http://#{@username}:#{@password}@#{@host}:#{@port}/crx/packmgr/service.jsp?cmd=ls")).body
|
53
|
+
doc = REXML::Document.new(xml_data)
|
54
|
+
|
55
|
+
packages = Array.new
|
56
|
+
doc.elements.each("//response/data/packages/package") do |ele|
|
57
|
+
package = Hash.new
|
58
|
+
packages << package
|
59
|
+
ele.elements.each do |child|
|
60
|
+
package[child.name] = child.text
|
61
|
+
end
|
62
|
+
end
|
63
|
+
return packages
|
64
|
+
end
|
65
|
+
|
66
|
+
def upload_package(package_file)
|
67
|
+
results = AdobeCRX::PackageUtils.get_package_properties(package_file)
|
68
|
+
File.open(package_file) do |package|
|
69
|
+
req = Net::HTTP::Post::Multipart.new(
|
70
|
+
'/crx/packmgr/service/.json/?cmd=upload',
|
71
|
+
'force' => 'true',
|
72
|
+
'package' => UploadIO.new(package, 'application/zip', File.basename(package_file))
|
73
|
+
)
|
74
|
+
req.basic_auth(@username, @password)
|
75
|
+
Net::HTTP.start(@host, @port) do |http|
|
76
|
+
response = http.request(req)
|
77
|
+
results.merge! JSON.parse(response.body)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
results
|
81
|
+
end
|
82
|
+
|
83
|
+
def install_package(path)
|
84
|
+
req = Net::HTTP::Post.new("/crx/packmgr/service/.json#{path}?cmd=install")
|
85
|
+
req.basic_auth(@username, @password)
|
86
|
+
result = Hash.new
|
87
|
+
Net::HTTP.start(@host, @port) do |http|
|
88
|
+
response = http.request(req)
|
89
|
+
result.merge! JSON.parse(response.body)
|
90
|
+
end
|
91
|
+
result
|
92
|
+
end
|
93
|
+
|
94
|
+
def remove_package(path)
|
95
|
+
req = Net::HTTP::Post.new("/crx/packmgr/service/.json#{path}?cmd=delete")
|
96
|
+
req.basic_auth(@username, @password)
|
97
|
+
result = Hash.new
|
98
|
+
Net::HTTP.start(@host, @port) do |http|
|
99
|
+
response = http.request(req)
|
100
|
+
result.merge! JSON.parse(response.body)
|
101
|
+
end
|
102
|
+
result
|
103
|
+
end
|
104
|
+
|
105
|
+
def export_package(package, dest_file = nil)
|
106
|
+
#create the package
|
107
|
+
req = Net::HTTP::Post.new('/crx/packmgr/service/.json/etc/packages/my_packages?cmd=create')
|
108
|
+
req.basic_auth(@username, @password)
|
109
|
+
params = Hash.new
|
110
|
+
params['packageName'] = package.name
|
111
|
+
params['groupName'] = 'automated-exports'
|
112
|
+
req.set_form_data(params)
|
113
|
+
create_result = nil
|
114
|
+
Net::HTTP.start(@host, @port) do |http|
|
115
|
+
response = http.request(req)
|
116
|
+
create_result = JSON.parse(response.body)
|
117
|
+
if !create_result['success']
|
118
|
+
raise AdobeCRX::CRXException, create_result['msg']
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
#add the filters
|
123
|
+
req = Net::HTTP::Post::Multipart.new(
|
124
|
+
'/crx/packmgr/update.jsp',
|
125
|
+
'_charset_' => 'utf-8',
|
126
|
+
'path' => create_result['path'],
|
127
|
+
'packageName' => package.name,
|
128
|
+
'groupName' => 'automated-exports',
|
129
|
+
'filter' => package.filters.to_json
|
130
|
+
)
|
131
|
+
req.basic_auth(@username, @password)
|
132
|
+
Net::HTTP.start(@host, @port) do |http|
|
133
|
+
response = http.request(req)
|
134
|
+
result = JSON.parse(response.body)
|
135
|
+
if !result['success']
|
136
|
+
raise AdobeCRX::CRXException, create_result['msg']
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
#build the package
|
141
|
+
req = Net::HTTP::Post.new("/crx/packmgr/service/.json#{create_result['path']}?cmd=build")
|
142
|
+
req.basic_auth(@username, @password)
|
143
|
+
Net::HTTP.start(@host, @port) do |http|
|
144
|
+
http.read_timeout = 1800
|
145
|
+
response = http.request(req)
|
146
|
+
result = JSON.parse(response.body)
|
147
|
+
if !result['success']
|
148
|
+
raise AdobeCRX::CRXException, create_result['msg']
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
#download the package
|
153
|
+
file_path = dest_file ? dest_file : "#{Dir.tmpdir}/#{package.name}"
|
154
|
+
req = Net::HTTP::Get.new(create_result['path'])
|
155
|
+
req.basic_auth(@username, @password)
|
156
|
+
Net::HTTP.start(@host, @port) do |http|
|
157
|
+
f = File.open(file_path, 'w')
|
158
|
+
begin
|
159
|
+
http.request(req) do |resp|
|
160
|
+
resp.read_body do |segment|
|
161
|
+
f.write(segment)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
ensure
|
165
|
+
f.close()
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
#delete the package
|
170
|
+
remove_package(create_result['path'])
|
171
|
+
|
172
|
+
file_path
|
173
|
+
end
|
174
|
+
|
175
|
+
def import_package(package_file)
|
176
|
+
upload_result = upload_package(package_file)
|
177
|
+
if !upload_result['success'] || upload_result['path'] == nil
|
178
|
+
raise AdobeCRX::CRXException, "Error uploading package: #{upload_result['msg']}"
|
179
|
+
end
|
180
|
+
install_result = install_package(upload_result['path'])
|
181
|
+
if !install_result['success']
|
182
|
+
raise AdobeCRX::CRXException, "Error installing package: #{install_result['msg']}"
|
183
|
+
end
|
184
|
+
remove_package(upload_result['path'])
|
185
|
+
result = "successfully deployed package at #{package_file}:"
|
186
|
+
upload_result.each do |key, value|
|
187
|
+
result << "\n #{key}: #{value}"
|
188
|
+
end
|
189
|
+
result
|
190
|
+
end
|
191
|
+
|
192
|
+
#content methods
|
193
|
+
def get_child_resources(path)
|
194
|
+
if !@dav
|
195
|
+
@dav = Net::DAV.new("http://#{@host}:#{@port}", :curl => false)
|
196
|
+
@dav.credentials(@username, @password)
|
197
|
+
end
|
198
|
+
|
199
|
+
resources = Array.new
|
200
|
+
@dav.find(path,:recursive=>false,:suppress_errors=>true) do | item |
|
201
|
+
resources << item.uri.path.sub(/\/$/, '')
|
202
|
+
end
|
203
|
+
resources
|
204
|
+
end
|
205
|
+
|
206
|
+
def get_node_structure(path, parent = nil)
|
207
|
+
if !@dav
|
208
|
+
@dav = Net::DAV.new("http://#{@host}:#{@port}", :curl => false)
|
209
|
+
@dav.credentials(@username, @password)
|
210
|
+
end
|
211
|
+
node = AdobeCRX::Node.new path
|
212
|
+
if parent
|
213
|
+
parent.children << node
|
214
|
+
end
|
215
|
+
begin
|
216
|
+
node.size = @dav.propfind_size("#{path}/jcr:content")
|
217
|
+
rescue Exception
|
218
|
+
#nothing
|
219
|
+
end
|
220
|
+
@dav.find(path,:recursive=>false,:suppress_errors=>true) do | item |
|
221
|
+
if path != item.uri.path
|
222
|
+
get_node_structure(item.uri.path.sub(/\/$/, ''), node)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
node
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class AdobeCRX::Node
|
2
|
+
attr_accessor :path, :size, :children
|
3
|
+
|
4
|
+
def initialize(path)
|
5
|
+
@path = path
|
6
|
+
@size = 0
|
7
|
+
@children = []
|
8
|
+
@cached_size = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def children_size
|
12
|
+
@children.inject(0) {|sum, n| sum + n.size }
|
13
|
+
end
|
14
|
+
|
15
|
+
def total_size
|
16
|
+
if !@cached_size
|
17
|
+
@cached_size = @size + (@children.inject(0) {|sum, n| sum + n.total_size })
|
18
|
+
end
|
19
|
+
@cached_size
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class AdobeCRX::Package
|
2
|
+
attr_accessor :name, :filters, :properties
|
3
|
+
|
4
|
+
def initialize(name)
|
5
|
+
@name = name
|
6
|
+
@filters = []
|
7
|
+
@properties = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_json(*a)
|
11
|
+
{
|
12
|
+
'name' => name,
|
13
|
+
'filters' => filters
|
14
|
+
}.to_json(*a)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class AdobeCRX::PackageFilterRule
|
2
|
+
attr_accessor :modifier, :pattern
|
3
|
+
|
4
|
+
def initialize(modifier, pattern)
|
5
|
+
@modifier = modifier
|
6
|
+
@pattern = pattern
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_json(*a)
|
10
|
+
{
|
11
|
+
'modifier' => modifier,
|
12
|
+
'pattern' => pattern
|
13
|
+
}.to_json(*a)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'zip/zip'
|
2
|
+
require 'rexml/document'
|
3
|
+
|
4
|
+
class AdobeCRX::PackageUtils
|
5
|
+
def self.get_package_properties(package_file)
|
6
|
+
Zip::ZipFile.open(package_file, Zip::ZipFile::CREATE) do |zipfile|
|
7
|
+
doc = REXML::Document.new(zipfile.read("META-INF/vault/properties.xml"))
|
8
|
+
properties = Hash.new
|
9
|
+
doc.elements.each("//properties/entry") do |ele|
|
10
|
+
properties[ele.attributes['key']] = ele.text
|
11
|
+
end
|
12
|
+
return properties
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class AdobeCRX::UberPackage
|
2
|
+
attr_accessor :name, :packages
|
3
|
+
|
4
|
+
def initialize(name)
|
5
|
+
@name = name
|
6
|
+
@packages = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_json(*a)
|
10
|
+
{
|
11
|
+
'name' => name,
|
12
|
+
'packages' => packages
|
13
|
+
}.to_json(*a)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.from_json(json)
|
17
|
+
data = JSON.parse(json)
|
18
|
+
uber = AdobeCRX::UberPackage.new data['name']
|
19
|
+
data['packages'].each do |p|
|
20
|
+
package = AdobeCRX::Package.new p['name']
|
21
|
+
uber.packages << package
|
22
|
+
p['filters'].each do |f|
|
23
|
+
filter = AdobeCRX::PackageFilter.new f['root']
|
24
|
+
package.filters << filter
|
25
|
+
f['rules'].each do |r|
|
26
|
+
filter.rules << AdobeCRX::PackageFilterRule.new(r['modifier'], r['pattern'])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
uber
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class AdobeCRX::UberPackageManager
|
4
|
+
def initialize(client)
|
5
|
+
@client = client
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate_uber_package_definition(name, root_path, options = {})
|
9
|
+
opts = {
|
10
|
+
:target_package_size => 0,
|
11
|
+
:root_package_depth => 1 #if 0, what's the point of creating an uber package?
|
12
|
+
}.merge(options)
|
13
|
+
|
14
|
+
root_node = get_node_structure(root_path, opts, 0)
|
15
|
+
|
16
|
+
uber = AdobeCRX::UberPackage.new name
|
17
|
+
root_package = AdobeCRX::Package.new "#{name}-root"
|
18
|
+
uber.packages << root_package
|
19
|
+
root_filter = AdobeCRX::PackageFilter.new root_path
|
20
|
+
root_package.filters << root_filter
|
21
|
+
root_package.properties[:size] = root_node.size
|
22
|
+
process_node_for_uber(name, root_node, uber.packages, root_package, opts, 0)
|
23
|
+
|
24
|
+
JSON.pretty_generate(JSON.parse(uber.to_json))
|
25
|
+
end
|
26
|
+
|
27
|
+
def export_uber_package(uber_package_definition, dest_dir = nil)
|
28
|
+
manifest_file = File.open(uber_package_definition, "rb")
|
29
|
+
uber = AdobeCRX::UberPackage.from_json manifest_file.read
|
30
|
+
|
31
|
+
uber_dir = dest_dir ? dest_dir : "#{Dir.tmpdir}/uber_packages/#{uber.name}"
|
32
|
+
FileUtils.mkpath uber_dir
|
33
|
+
|
34
|
+
#export the packages to the uber_dir
|
35
|
+
uber.packages.each do |package|
|
36
|
+
puts "exporting #{package.name}..."
|
37
|
+
@client.export_package package, "#{uber_dir}/#{package.name}.zip"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def import_uber_package(uber_package_definition, uber_package_dir)
|
42
|
+
manifest_file = File.open(uber_package_definition, "rb")
|
43
|
+
uber = AdobeCRX::UberPackage.from_json manifest_file.read
|
44
|
+
|
45
|
+
#import the packages to the target crx instance
|
46
|
+
uber.packages.each do |package|
|
47
|
+
puts "importing #{package.name}..."
|
48
|
+
p_file = "#{uber_package_dir}/#{package.name}.zip"
|
49
|
+
if File.exist? p_file
|
50
|
+
@client.import_package p_file
|
51
|
+
else
|
52
|
+
puts "ERROR: package does not exist at '#{p_file}'"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def get_node_structure(path, options, current_level, parent_node = nil)
|
60
|
+
if options[:root_package_depth] > current_level
|
61
|
+
node = AdobeCRX::Node.new path
|
62
|
+
@client.get_child_resources(path).each do |child_path|
|
63
|
+
get_node_structure(child_path, options, current_level + 1, node)
|
64
|
+
end
|
65
|
+
elsif options[:target_package_size] > 0
|
66
|
+
node = @client.get_node_structure path
|
67
|
+
else
|
68
|
+
node = AdobeCRX::Node.new path
|
69
|
+
@client.get_child_resources(path).each do |child_path|
|
70
|
+
node.children << AdobeCRX::Node.new(child_path)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
if parent_node
|
74
|
+
parent_node.children << node
|
75
|
+
end
|
76
|
+
node
|
77
|
+
end
|
78
|
+
|
79
|
+
def process_node_for_uber(name, node, packages, current_package, options, current_level)
|
80
|
+
#puts "#{node.path}: #{current_package.properties[:size]}, #{node.size}, #{node.children_size}, #{node.total_size}"
|
81
|
+
if options[:root_package_depth] > 0 && options[:root_package_depth] > current_level
|
82
|
+
node.children.each do |child|
|
83
|
+
process_node_for_uber(name, child, packages, current_package, options, current_level + 1)
|
84
|
+
end
|
85
|
+
elsif options[:root_package_depth] > 0 && options[:root_package_depth] == current_level
|
86
|
+
current_package.filters[0].rules << AdobeCRX::PackageFilterRule.new('exclude', node.path)
|
87
|
+
current_package.filters[0].rules << AdobeCRX::PackageFilterRule.new('exclude', "#{node.path}/.*")
|
88
|
+
new_package = AdobeCRX::Package.new "#{name}-#{node.path}".gsub('/', '-').gsub(' ', '_').gsub("%20", '_')
|
89
|
+
packages << new_package
|
90
|
+
new_filter = AdobeCRX::PackageFilter.new node.path
|
91
|
+
new_package.filters << new_filter
|
92
|
+
new_package.properties[:size] = node.size
|
93
|
+
node.children.each do |child|
|
94
|
+
process_node_for_uber(name, child, packages, new_package, options, current_level + 1)
|
95
|
+
end
|
96
|
+
elsif node.total_size > 0
|
97
|
+
branch_to_new_package = (
|
98
|
+
((node.size + current_package.properties[:size]) > options[:target_package_size]) ||
|
99
|
+
((node.children_size + current_package.properties[:size]) > options[:target_package_size])
|
100
|
+
)
|
101
|
+
|
102
|
+
if branch_to_new_package
|
103
|
+
current_package.filters[0].rules << AdobeCRX::PackageFilterRule.new('exclude', node.path)
|
104
|
+
current_package.filters[0].rules << AdobeCRX::PackageFilterRule.new('exclude', "#{node.path}/.*")
|
105
|
+
new_package = AdobeCRX::Package.new "#{name}-#{node.path}".gsub('/', '-').gsub(' ', '_').gsub("%20", '_')
|
106
|
+
packages << new_package
|
107
|
+
new_filter = AdobeCRX::PackageFilter.new node.path
|
108
|
+
new_package.filters << new_filter
|
109
|
+
new_package.properties[:size] = node.size
|
110
|
+
node.children.each do |child|
|
111
|
+
process_node_for_uber(name, child, packages, new_package, options, current_level + 1)
|
112
|
+
end
|
113
|
+
else
|
114
|
+
current_package.properties[:size] = current_package.properties[:size] + node.size
|
115
|
+
node.children.each do |child|
|
116
|
+
process_node_for_uber(name, child, packages, current_package, options, current_level + 1)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
ADOBE_CRX_VERSION = "0.0.1"
|
data/lib/adobe_crx.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module AdobeCRX
|
2
|
+
class CRXException < RuntimeError
|
3
|
+
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'adobe_crx/client'
|
8
|
+
require 'adobe_crx/node'
|
9
|
+
require 'adobe_crx/package'
|
10
|
+
require 'adobe_crx/package_filter'
|
11
|
+
require 'adobe_crx/package_filter_rule'
|
12
|
+
require 'adobe_crx/package_utils'
|
13
|
+
require 'adobe_crx/uber_package'
|
14
|
+
require 'adobe_crx/uber_package_manager'
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: adobe_crx
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Todd Tomkinson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-09 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: &24061300 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *24061300
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rubyzip
|
27
|
+
requirement: &24060880 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *24060880
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: multipart-post
|
38
|
+
requirement: &24060460 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *24060460
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: net_dav
|
49
|
+
requirement: &24060040 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *24060040
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: commander
|
60
|
+
requirement: &24059620 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *24059620
|
69
|
+
description: Ruby client used to manage day/adobe crx instances. Also includes utilities
|
70
|
+
for performing common maintenance tasks.
|
71
|
+
email:
|
72
|
+
- todd.g.tomkinson@gmail.com
|
73
|
+
executables:
|
74
|
+
- crx
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- lib/adobe_crx.rb
|
79
|
+
- lib/adobe_crx/uber_package.rb
|
80
|
+
- lib/adobe_crx/cli/import_uber.rb
|
81
|
+
- lib/adobe_crx/cli/import.rb
|
82
|
+
- lib/adobe_crx/cli/export.rb
|
83
|
+
- lib/adobe_crx/cli/generate_uber_manifest.rb
|
84
|
+
- lib/adobe_crx/cli/export_uber.rb
|
85
|
+
- lib/adobe_crx/client.rb
|
86
|
+
- lib/adobe_crx/package.rb
|
87
|
+
- lib/adobe_crx/version.rb
|
88
|
+
- lib/adobe_crx/cli.rb
|
89
|
+
- lib/adobe_crx/package_filter.rb
|
90
|
+
- lib/adobe_crx/package_utils.rb
|
91
|
+
- lib/adobe_crx/package_filter_rule.rb
|
92
|
+
- lib/adobe_crx/node.rb
|
93
|
+
- lib/adobe_crx/uber_package_manager.rb
|
94
|
+
- bin/crx
|
95
|
+
homepage: https://github.com/toddtomkinson/adobe_crx
|
96
|
+
licenses:
|
97
|
+
- Apache License (2.0)
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 1.8.10
|
118
|
+
signing_key:
|
119
|
+
specification_version: 3
|
120
|
+
summary: ruby client used to manage day/adobe crx instances
|
121
|
+
test_files: []
|