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.
Files changed (2) hide show
  1. data/lib/quilt.rb +214 -0
  2. 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: []