ruby-quilt 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/lib/quilt.rb +214 -0
- metadata +135 -0
data/lib/quilt.rb
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'json'
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
class Quilt
|
6
|
+
HEADER_KEY = "header"
|
7
|
+
COMMON_KEY = "common"
|
8
|
+
OPTIONAL_KEY = "optional"
|
9
|
+
FOOTER_KEY = "footer"
|
10
|
+
|
11
|
+
def initialize(config, log = Logger.new(STDOUT))
|
12
|
+
@config = config;
|
13
|
+
@versions = {};
|
14
|
+
@log = log
|
15
|
+
|
16
|
+
if (config[:local_path])
|
17
|
+
Dir.foreach(config[:local_path]) do |version_dir|
|
18
|
+
next if version_dir == "." || version_dir == ".."
|
19
|
+
@versions[version_dir] = load_version(config[:local_path], version_dir)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
throw "Quilt: local path not specified";
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def log_error(msg, e = nil)
|
27
|
+
return unless @log && @log.error?
|
28
|
+
@log.error(msg) if msg
|
29
|
+
if (e)
|
30
|
+
@log.error(e.message)
|
31
|
+
@log.error(e.backtrace.inspect)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def log_debug(msg)
|
36
|
+
return unless @log && @log.debug?
|
37
|
+
@log.debug(msg)
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_module_name(filename)
|
41
|
+
return nil unless filename
|
42
|
+
matches = filename.match(/(^.*\/|^)(.*)\.js$/)
|
43
|
+
return nil unless matches && matches.length >= 3
|
44
|
+
matches[2]
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_module(filename, dependancies, version_dir)
|
48
|
+
tmp_module = {}
|
49
|
+
tmp_module[:dependancies] = dependancies.is_a?(Array) ? dependancies :
|
50
|
+
(dependancies.is_a?(String) ? [ dependancies ] :
|
51
|
+
[])
|
52
|
+
begin
|
53
|
+
tmp_module[:module] = File.open(File.join(version_dir, filename), "rb").read
|
54
|
+
rescue Exception => e
|
55
|
+
log_error(" Could not load module: #{filename}", e)
|
56
|
+
return nil
|
57
|
+
end
|
58
|
+
tmp_module
|
59
|
+
end
|
60
|
+
|
61
|
+
def load_version(local_path, version_name)
|
62
|
+
log_debug("Loading Version: "+version_name)
|
63
|
+
manifest = {}
|
64
|
+
newVersion = {
|
65
|
+
:name => version_name,
|
66
|
+
:dir => File.join(local_path, version_name),
|
67
|
+
:base => '',
|
68
|
+
:modules => {}
|
69
|
+
}
|
70
|
+
begin
|
71
|
+
manifest = JSON.parse(File.read(File.join(newVersion[:dir], "manifest.json")))
|
72
|
+
rescue Exception => e
|
73
|
+
log_error(" Could not read manifest!", e);
|
74
|
+
return nil
|
75
|
+
end
|
76
|
+
# manifest.json:
|
77
|
+
# {
|
78
|
+
# "header" : "<header file>",
|
79
|
+
# "footer" : "<footer file>",
|
80
|
+
# "common" : [
|
81
|
+
# "<module file>",
|
82
|
+
# ...
|
83
|
+
# ],
|
84
|
+
# "optional" : {
|
85
|
+
# "<module file>" : [ "<dependancy module name>", ... ],
|
86
|
+
# ...
|
87
|
+
# }
|
88
|
+
# }
|
89
|
+
if manifest[HEADER_KEY]
|
90
|
+
begin
|
91
|
+
newVersion[:base] = "#{newVersion[:base]}#{File.open(File.join(newVersion[:dir],
|
92
|
+
manifest[HEADER_KEY]), "rb").read}"
|
93
|
+
rescue Exception => e
|
94
|
+
log_error(" Could not load header: #{manifest[HEADER_KEY]}", e)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
if manifest[COMMON_KEY] && manifest[COMMON_KEY].is_a?(Array)
|
98
|
+
manifest[COMMON_KEY].each do |filename|
|
99
|
+
begin
|
100
|
+
newVersion[:base] = "#{newVersion[:base]}#{File.open(File.join(newVersion[:dir],
|
101
|
+
filename), "rb").read}"
|
102
|
+
rescue Exception => e
|
103
|
+
log_error(" Could not load common module: #{filename}", e)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
if manifest[OPTIONAL_KEY] && manifest[OPTIONAL_KEY].is_a?(Hash)
|
108
|
+
manifest[OPTIONAL_KEY].each do |filename, dependancies|
|
109
|
+
tmp_module = get_module(filename, dependancies, newVersion[:dir])
|
110
|
+
if (tmp_module)
|
111
|
+
tmp_module_name = get_module_name(filename)
|
112
|
+
if (tmp_module_name)
|
113
|
+
newVersion[:modules][tmp_module_name] = tmp_module
|
114
|
+
else
|
115
|
+
log_error(" Could not extract module name from: #{filename}")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
if manifest[FOOTER_KEY]
|
121
|
+
begin
|
122
|
+
newVersion[:footer] = File.open(File.join(newVersion[:dir], manifest[FOOTER_KEY]), "rb").read
|
123
|
+
rescue Exception => e
|
124
|
+
log_error(" Could not load footer: #{manifest[FOOTER_KEY]}", e)
|
125
|
+
newVersion[FOOTER_KEY] = nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
newVersion
|
129
|
+
end
|
130
|
+
|
131
|
+
def resolve_dependancies(modules, version, all_modules = {})
|
132
|
+
out = ''
|
133
|
+
return out if !modules || !(modules.is_a?(Array)) || modules.empty?
|
134
|
+
my_all_modules = all_modules
|
135
|
+
modules.each do |name|
|
136
|
+
break if my_all_modules[name] == 2
|
137
|
+
if (!version[:modules][name] || !version[:modules][name][:module])
|
138
|
+
log_error(" invalid module: #{name}");
|
139
|
+
my_all_modules[name] = 2
|
140
|
+
break
|
141
|
+
end
|
142
|
+
if (my_all_modules[name] == 1)
|
143
|
+
log_error(" circular module dependancy: #{name}")
|
144
|
+
break
|
145
|
+
end
|
146
|
+
my_all_modules[name] = 1
|
147
|
+
out = "#{out}#{resolve_dependancies(version[:modules][name][:dependancies], version, my_all_modules)}"
|
148
|
+
out = "#{out}#{version[:modules][name][:module]}"
|
149
|
+
my_all_modules[name] = 2
|
150
|
+
end
|
151
|
+
out
|
152
|
+
end
|
153
|
+
|
154
|
+
def get_version(name)
|
155
|
+
return @versions[name] if @versions[name]
|
156
|
+
if (!@config[:remote_host] || !@config[:remote_path])
|
157
|
+
log_error("unable to load from host: #{@config[:remote_host]}, path: #{@config[:remote_path]}")
|
158
|
+
return nil
|
159
|
+
end
|
160
|
+
port = @config[:remote_port] ? @config[:remote_port].to_i : 80
|
161
|
+
# Fetch the version
|
162
|
+
filename = "#{name}.tgz"
|
163
|
+
begin
|
164
|
+
Net::HTTP.start(@config[:remote_host].to_s, port) do |http|
|
165
|
+
res = http.get("#{@config[:remote_path].to_s}#{name}.tgz")
|
166
|
+
if (res.code != "200")
|
167
|
+
log_error("no version fetched : #{res.code}")
|
168
|
+
return nil
|
169
|
+
end
|
170
|
+
open(File.join(@config[:local_path], filename), "wb") do |file|
|
171
|
+
file.write(res.body)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
rescue Exception => e
|
175
|
+
log_error("could not fetch version", e)
|
176
|
+
return nil
|
177
|
+
end
|
178
|
+
# Untar the version
|
179
|
+
tar_output = `cd #{@config[:local_path]} && tar -xzf #{filename} 2>&1`
|
180
|
+
if ($?.to_i != 0)
|
181
|
+
log_error("unable to untar package")
|
182
|
+
log_error(tar_output)
|
183
|
+
`cd #{@config[:local_path]} && rm #{filename}`
|
184
|
+
return nil
|
185
|
+
end
|
186
|
+
`cd #{@config[:local_path]} && rm #{filename}`
|
187
|
+
# Load the version
|
188
|
+
@versions[name] = load_version(@config[:local_path], name)
|
189
|
+
end
|
190
|
+
|
191
|
+
def stitch(selector, version_name)
|
192
|
+
return '' if !selector
|
193
|
+
version = get_version(version_name)
|
194
|
+
if (!version)
|
195
|
+
log_error("could not fetch version: #{version_name}")
|
196
|
+
return ''
|
197
|
+
end
|
198
|
+
|
199
|
+
# get modules we want to use
|
200
|
+
modules = []
|
201
|
+
if (selector.is_a?(Proc))
|
202
|
+
modules = version[:modules].keys.select do |mod|
|
203
|
+
selector.call(mod)
|
204
|
+
end
|
205
|
+
elsif (selector.is_a?(Array))
|
206
|
+
modules = selector
|
207
|
+
end
|
208
|
+
|
209
|
+
# resolve dependancies
|
210
|
+
output = "#{version[:base]}#{resolve_dependancies(modules, version, {})}#{version[:footer] ?
|
211
|
+
version[:footer] :
|
212
|
+
''}"
|
213
|
+
end
|
214
|
+
end
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-quilt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jigish Patel
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-26 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.6'
|
22
|
+
- - ! '>='
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.6.6
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.6'
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 1.6.6
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0.8'
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.8.7
|
47
|
+
type: :development
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.8'
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.8.7
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: scope
|
60
|
+
requirement: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0.2'
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.2.3
|
69
|
+
type: :development
|
70
|
+
prerelease: false
|
71
|
+
version_requirements: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0.2'
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 0.2.3
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: simplecov
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0.5'
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.5.3
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ~>
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0.5'
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.5.3
|
102
|
+
description: A file stitcher that maintains versions and can fetch additional versions
|
103
|
+
from a server.
|
104
|
+
email: x-device-team@ooyala.com
|
105
|
+
executables: []
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files: []
|
108
|
+
files:
|
109
|
+
- lib/quilt.rb
|
110
|
+
homepage: http://github.com/ooyala/ruby-quilt
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ! '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 1.9.2
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 1.8.23
|
132
|
+
signing_key:
|
133
|
+
specification_version: 3
|
134
|
+
summary: A File stitcher
|
135
|
+
test_files: []
|