fig 0.1.39-java → 0.1.41-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/Changes +45 -0
- data/LICENSE +2 -2
- data/README.md +154 -100
- data/VERSION +1 -0
- data/bin/fig +4 -182
- data/lib/fig.rb +222 -0
- data/lib/fig/applicationconfiguration.rb +52 -0
- data/lib/fig/backtrace.rb +6 -6
- data/lib/fig/configfileerror.rb +15 -0
- data/lib/fig/environment.rb +46 -26
- data/lib/fig/figrc.rb +105 -0
- data/lib/fig/grammar.treetop +1 -1
- data/lib/fig/log4rconfigerror.rb +14 -0
- data/lib/fig/logging.rb +131 -0
- data/lib/fig/networkerror.rb +7 -0
- data/lib/fig/notfounderror.rb +4 -0
- data/lib/fig/options.rb +191 -54
- data/lib/fig/os.rb +73 -74
- data/lib/fig/package.rb +30 -30
- data/lib/fig/packageerror.rb +7 -0
- data/lib/fig/parser.rb +5 -8
- data/lib/fig/repository.rb +44 -28
- data/lib/fig/repositoryerror.rb +7 -0
- data/lib/fig/retriever.rb +26 -17
- data/lib/fig/urlaccesserror.rb +9 -0
- data/lib/fig/userinputerror.rb +4 -0
- data/lib/fig/windows.rb +3 -3
- metadata +115 -21
data/lib/fig/os.rb
CHANGED
@@ -10,23 +10,24 @@ require 'net/netrc'
|
|
10
10
|
require 'tempfile'
|
11
11
|
require 'highline/import'
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
require 'fig/logging'
|
14
|
+
require 'fig/networkerror'
|
15
|
+
require 'fig/notfounderror'
|
16
16
|
|
17
|
+
module Fig
|
17
18
|
class OS
|
18
19
|
def initialize(login)
|
19
20
|
@login = login
|
20
|
-
@username = ENV[
|
21
|
-
@password = ENV[
|
21
|
+
@username = ENV['FIG_USERNAME']
|
22
|
+
@password = ENV['FIG_PASSWORD']
|
22
23
|
end
|
23
24
|
|
24
25
|
def get_username()
|
25
|
-
@username ||= ask(
|
26
|
+
@username ||= ask('Username: ') { |q| q.echo = true }
|
26
27
|
end
|
27
|
-
|
28
|
+
|
28
29
|
def get_password()
|
29
|
-
@password ||= ask(
|
30
|
+
@password ||= ask('Password: ') { |q| q.echo = false }
|
30
31
|
end
|
31
32
|
|
32
33
|
def ftp_login(ftp, host)
|
@@ -37,7 +38,7 @@ module Fig
|
|
37
38
|
@password = rc.password
|
38
39
|
end
|
39
40
|
ftp.login(get_username, get_password)
|
40
|
-
else
|
41
|
+
else
|
41
42
|
ftp.login()
|
42
43
|
end
|
43
44
|
ftp.passive = true
|
@@ -46,36 +47,36 @@ module Fig
|
|
46
47
|
def list(dir)
|
47
48
|
Dir.entries(dir) - ['.','..']
|
48
49
|
end
|
49
|
-
|
50
|
+
|
50
51
|
def exist?(path)
|
51
52
|
File.exist?(path)
|
52
53
|
end
|
53
|
-
|
54
|
+
|
54
55
|
def mtime(path)
|
55
56
|
File.mtime(path)
|
56
57
|
end
|
57
|
-
|
58
|
+
|
58
59
|
def read(path)
|
59
60
|
File.read(path)
|
60
61
|
end
|
61
|
-
|
62
|
+
|
62
63
|
def write(path, content)
|
63
|
-
File.open(path,
|
64
|
+
File.open(path, 'wb') { |f| f.binmode; f << content }
|
64
65
|
end
|
65
|
-
|
66
|
+
|
66
67
|
SUCCESS = 0
|
67
68
|
NOT_MODIFIED = 3
|
68
69
|
NOT_FOUND = 4
|
69
|
-
|
70
|
+
|
70
71
|
def download_list(url)
|
71
72
|
begin
|
72
73
|
uri = URI.parse(url)
|
73
|
-
rescue
|
74
|
-
|
75
|
-
|
74
|
+
rescue
|
75
|
+
Logging.fatal %Q<Unable to parse url: "#{url}">
|
76
|
+
raise NetworkError.new
|
76
77
|
end
|
77
78
|
case uri.scheme
|
78
|
-
when
|
79
|
+
when 'ftp'
|
79
80
|
ftp = Net::FTP.new(uri.host)
|
80
81
|
ftp_login(ftp, uri.host)
|
81
82
|
ftp.chdir(uri.path)
|
@@ -83,12 +84,12 @@ module Fig
|
|
83
84
|
ftp.close
|
84
85
|
|
85
86
|
download_ftp_list(uri, dirs)
|
86
|
-
when
|
87
|
+
when 'ssh'
|
87
88
|
packages = []
|
88
89
|
Net::SSH.start(uri.host, uri.user) do |ssh|
|
89
90
|
ls = ssh.exec!("[ -d #{uri.path} ] && find #{uri.path}")
|
90
91
|
if not ls.nil?
|
91
|
-
ls = ls.gsub(uri.path +
|
92
|
+
ls = ls.gsub(uri.path + '/', '').gsub(uri.path, '').split("\n")
|
92
93
|
ls.each do |line|
|
93
94
|
parts = line.gsub(/\\/, '/').sub(/^\.\//, '').sub(/:$/, '').chomp().split('/')
|
94
95
|
packages << parts.join('/') if parts.size == 2
|
@@ -97,16 +98,16 @@ module Fig
|
|
97
98
|
end
|
98
99
|
packages
|
99
100
|
else
|
100
|
-
|
101
|
-
|
101
|
+
Logging.fatal "Protocol not supported: #{url}"
|
102
|
+
raise NetworkError.new
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
105
106
|
def download_ftp_list(uri, dirs)
|
106
107
|
# Run a bunch of these in parallel since they're slow as hell
|
107
|
-
num_threads = (ENV[
|
108
|
+
num_threads = (ENV['FIG_FTP_THREADS'] || '16').to_i
|
108
109
|
threads = []
|
109
|
-
all_packages = []
|
110
|
+
all_packages = []
|
110
111
|
(0..num_threads-1).each { |num| all_packages[num] = [] }
|
111
112
|
(0..num_threads-1).each do |num|
|
112
113
|
threads << Thread.new do
|
@@ -137,46 +138,49 @@ module Fig
|
|
137
138
|
FileUtils.mkdir_p(File.dirname(path))
|
138
139
|
uri = URI.parse(url)
|
139
140
|
case uri.scheme
|
140
|
-
when
|
141
|
+
when 'ftp'
|
141
142
|
ftp = Net::FTP.new(uri.host)
|
142
143
|
ftp_login(ftp, uri.host)
|
143
144
|
begin
|
144
145
|
if File.exist?(path) && ftp.mtime(uri.path) <= File.mtime(path)
|
146
|
+
Logging.debug "#{path} is up to date."
|
145
147
|
return false
|
146
|
-
else
|
147
|
-
|
148
|
+
else
|
149
|
+
log_download(url, path)
|
148
150
|
ftp.getbinaryfile(uri.path, path, 256*1024)
|
149
151
|
return true
|
150
152
|
end
|
151
|
-
rescue Net::FTPPermError
|
152
|
-
|
153
|
+
rescue Net::FTPPermError => e
|
154
|
+
Logging.warn e
|
155
|
+
raise NotFoundError.new
|
153
156
|
end
|
154
|
-
when
|
157
|
+
when 'http'
|
155
158
|
http = Net::HTTP.new(uri.host)
|
156
|
-
|
157
|
-
File.open(path,
|
159
|
+
log_download(url, path)
|
160
|
+
File.open(path, 'wb') do |file|
|
158
161
|
file.binmode
|
159
162
|
http.get(uri.path) do |block|
|
160
163
|
file.write(block)
|
161
164
|
end
|
162
165
|
end
|
163
|
-
when
|
166
|
+
when 'ssh'
|
164
167
|
# TODO need better way to do conditional download
|
165
|
-
|
166
|
-
|
168
|
+
timestamp = File.exist?(path) ? File.mtime(path).to_i : 0
|
169
|
+
# Requires that remote installation of fig be at the same location as the local machine.
|
167
170
|
cmd = `which fig-download`.strip + " #{timestamp} #{uri.path}"
|
171
|
+
log_download(url, path)
|
168
172
|
ssh_download(uri.user, uri.host, path, cmd)
|
169
173
|
else
|
170
|
-
|
171
|
-
|
174
|
+
Logging.fatal "Unknown protocol: #{url}"
|
175
|
+
raise NetworkError.new
|
172
176
|
end
|
173
|
-
|
174
|
-
|
177
|
+
end
|
178
|
+
|
175
179
|
def download_resource(url, dir)
|
176
180
|
FileUtils.mkdir_p(dir)
|
177
181
|
download(url, File.join(dir, URI.parse(url).path.split('/').last))
|
178
182
|
end
|
179
|
-
|
183
|
+
|
180
184
|
def download_archive(url, dir)
|
181
185
|
FileUtils.mkdir_p(dir)
|
182
186
|
basename = URI.parse(url).path.split('/').last
|
@@ -192,25 +196,25 @@ module Fig
|
|
192
196
|
when /\.zip$/
|
193
197
|
unpack_archive(dir, path)
|
194
198
|
else
|
195
|
-
|
196
|
-
|
199
|
+
Logging.fatal "Unknown archive type: #{basename}"
|
200
|
+
raise NetworkError.new
|
197
201
|
end
|
198
202
|
end
|
199
|
-
|
203
|
+
|
200
204
|
def upload(local_file, remote_file, user)
|
201
|
-
|
205
|
+
Logging.debug "Uploading #{local_file} to #{remote_file}."
|
202
206
|
uri = URI.parse(remote_file)
|
203
207
|
case uri.scheme
|
204
|
-
when
|
208
|
+
when 'ssh'
|
205
209
|
ssh_upload(uri.user, uri.host, local_file, remote_file)
|
206
|
-
when
|
210
|
+
when 'ftp'
|
207
211
|
# fail unless system "curl -T #{local_file} --create-dirs --ftp-create-dirs #{remote_file}"
|
208
212
|
require 'net/ftp'
|
209
|
-
ftp_uri = URI.parse(ENV[
|
213
|
+
ftp_uri = URI.parse(ENV['FIG_REMOTE_URL'])
|
210
214
|
ftp_root_path = ftp_uri.path
|
211
|
-
ftp_root_dirs = ftp_uri.path.split(
|
212
|
-
remote_publish_path = uri.path[0, uri.path.rindex(
|
213
|
-
remote_publish_dirs = remote_publish_path.split(
|
215
|
+
ftp_root_dirs = ftp_uri.path.split('/')
|
216
|
+
remote_publish_path = uri.path[0, uri.path.rindex('/')]
|
217
|
+
remote_publish_dirs = remote_publish_path.split('/')
|
214
218
|
# Use array subtraction to deduce which project/version folder to upload to,
|
215
219
|
# i.e. [1,2,3] - [2,3,4] = [1]
|
216
220
|
remote_project_dirs = remote_publish_dirs - ftp_root_dirs
|
@@ -231,26 +235,17 @@ module Fig
|
|
231
235
|
end
|
232
236
|
end
|
233
237
|
end
|
234
|
-
|
238
|
+
|
235
239
|
def clear_directory(dir)
|
236
240
|
FileUtils.rm_rf(dir)
|
237
241
|
FileUtils.mkdir_p(dir)
|
238
242
|
end
|
239
243
|
|
240
|
-
def exec(dir,command)
|
241
|
-
Dir.chdir(dir) {
|
242
|
-
unless system command
|
243
|
-
$stderr.puts "Command failed"
|
244
|
-
exit 10
|
245
|
-
end
|
246
|
-
}
|
247
|
-
end
|
248
|
-
|
249
244
|
def copy(source, target, msg = nil)
|
250
245
|
if File.directory?(source)
|
251
246
|
FileUtils.mkdir_p(target)
|
252
247
|
Dir.foreach(source) do |child|
|
253
|
-
if child !=
|
248
|
+
if child != '.' and child != '..'
|
254
249
|
copy(File.join(source, child), File.join(target, child), msg)
|
255
250
|
end
|
256
251
|
end
|
@@ -267,9 +262,9 @@ module Fig
|
|
267
262
|
def move_file(dir, from, to)
|
268
263
|
Dir.chdir(dir) { FileUtils.mv(from, to, :force => true) }
|
269
264
|
end
|
270
|
-
|
265
|
+
|
271
266
|
def log_info(msg)
|
272
|
-
|
267
|
+
Logging.info msg
|
273
268
|
end
|
274
269
|
|
275
270
|
# Expects files_to_archive as an Array of filenames.
|
@@ -339,8 +334,8 @@ module Fig
|
|
339
334
|
end
|
340
335
|
|
341
336
|
def shell_exec_windows(cmd)
|
342
|
-
#command = [
|
343
|
-
command = [
|
337
|
+
#command = ['C:/WINDOWS/system32/cmd.exe', '/C', 'call'] + cmd
|
338
|
+
command = ['cmd.exe', '/C'] + cmd
|
344
339
|
command = command.join(' ')
|
345
340
|
Kernel.exec(command)
|
346
341
|
end
|
@@ -349,13 +344,13 @@ module Fig
|
|
349
344
|
# cmd = The command to be run on the remote host.
|
350
345
|
def ssh_download(user, host, path, cmd)
|
351
346
|
return_code = nil
|
352
|
-
tempfile = Tempfile.new(
|
347
|
+
tempfile = Tempfile.new('tmp')
|
353
348
|
Net::SSH.start(host, user) do |ssh|
|
354
349
|
ssh.open_channel do |channel|
|
355
350
|
channel.exec(cmd)
|
356
351
|
channel.on_data() { |ch, data| tempfile << data }
|
357
|
-
channel.on_extended_data() { |ch, type, data|
|
358
|
-
channel.on_request(
|
352
|
+
channel.on_extended_data() { |ch, type, data| Logging.error "SSH Download ERROR: #{data}" }
|
353
|
+
channel.on_request('exit-status') { |ch, request|
|
359
354
|
return_code = request.read_long
|
360
355
|
}
|
361
356
|
end
|
@@ -369,15 +364,14 @@ module Fig
|
|
369
364
|
return false
|
370
365
|
when NOT_FOUND
|
371
366
|
tempfile.delete
|
372
|
-
|
373
|
-
exit 10
|
367
|
+
raise NotFoundError.new
|
374
368
|
when SUCCESS
|
375
369
|
FileUtils.mv(tempfile.path, path)
|
376
370
|
return true
|
377
371
|
else
|
378
372
|
tempfile.delete
|
379
|
-
|
380
|
-
|
373
|
+
Logging.fatal "Unable to download file #{path}: #{return_code}"
|
374
|
+
raise NetworkError.new
|
381
375
|
end
|
382
376
|
end
|
383
377
|
|
@@ -392,5 +386,10 @@ module Fig
|
|
392
386
|
end
|
393
387
|
end
|
394
388
|
|
389
|
+
private
|
390
|
+
|
391
|
+
def log_download(url, path)
|
392
|
+
Logging.debug "Downloading #{url} to #{path}."
|
393
|
+
end
|
395
394
|
end
|
396
395
|
end
|
data/lib/fig/package.rb
CHANGED
@@ -1,22 +1,25 @@
|
|
1
|
+
require 'fig/logging'
|
2
|
+
require 'fig/packageerror'
|
3
|
+
|
1
4
|
module Fig
|
2
5
|
class Package
|
3
6
|
attr_reader :package_name, :version_name, :directory, :statements
|
4
7
|
attr_accessor :backtrace
|
5
|
-
|
6
|
-
def initialize(package_name, version_name, directory, statements)
|
8
|
+
|
9
|
+
def initialize(package_name, version_name, directory, statements)
|
7
10
|
@package_name = package_name
|
8
11
|
@version_name = version_name
|
9
12
|
@directory = directory
|
10
13
|
@statements = statements
|
11
14
|
@backtrace = nil
|
12
15
|
end
|
13
|
-
|
16
|
+
|
14
17
|
def [](config_name)
|
15
18
|
@statements.each do |stmt|
|
16
19
|
return stmt if stmt.is_a?(Configuration) && stmt.name == config_name
|
17
20
|
end
|
18
|
-
|
19
|
-
|
21
|
+
Fig::Logging.fatal "Configuration not found: #{@package_name}/#{@version_name}:#{config_name}"
|
22
|
+
raise PackageError.new
|
20
23
|
end
|
21
24
|
|
22
25
|
def configs
|
@@ -32,11 +35,11 @@ module Fig
|
|
32
35
|
def archive_urls
|
33
36
|
@statements.select{|s| s.is_a?(Archive)}.map{|s|s.url}
|
34
37
|
end
|
35
|
-
|
38
|
+
|
36
39
|
def resource_urls
|
37
40
|
@statements.select{|s| s.is_a?(Resource)}.map{|s|s.url}
|
38
41
|
end
|
39
|
-
|
42
|
+
|
40
43
|
def unparse
|
41
44
|
@statements.map { |statement| statement.unparse('') }.join("\n")
|
42
45
|
end
|
@@ -46,34 +49,34 @@ module Fig
|
|
46
49
|
end
|
47
50
|
|
48
51
|
def to_s
|
49
|
-
@package_name +
|
52
|
+
@package_name + '/' + @version_name
|
50
53
|
end
|
51
54
|
end
|
52
|
-
|
55
|
+
|
53
56
|
class Archive
|
54
57
|
attr_reader :url
|
55
|
-
|
58
|
+
|
56
59
|
def initialize(url)
|
57
60
|
@url = url
|
58
61
|
end
|
59
|
-
|
62
|
+
|
60
63
|
def unparse(indent)
|
61
|
-
|
64
|
+
%Q<#{indent}archive "#{url}">
|
62
65
|
end
|
63
66
|
end
|
64
|
-
|
67
|
+
|
65
68
|
class Resource
|
66
69
|
attr_reader :url
|
67
|
-
|
70
|
+
|
68
71
|
def initialize(url)
|
69
72
|
@url = url
|
70
73
|
end
|
71
|
-
|
74
|
+
|
72
75
|
def unparse(indent)
|
73
76
|
"#{indent}resource #{url}"
|
74
77
|
end
|
75
78
|
end
|
76
|
-
|
79
|
+
|
77
80
|
class Retrieve
|
78
81
|
attr_reader :var, :path
|
79
82
|
|
@@ -94,7 +97,7 @@ module Fig
|
|
94
97
|
@local_name = local_name
|
95
98
|
@remote_name = remote_name
|
96
99
|
end
|
97
|
-
|
100
|
+
|
98
101
|
def unparse(indent)
|
99
102
|
"#{indent}publish #{@local_name}->#{@remote_name}"
|
100
103
|
end
|
@@ -110,9 +113,9 @@ module Fig
|
|
110
113
|
body = @statements.map { |statement| statement.unparse(indent+' ') }.join("\n")
|
111
114
|
suffix = "#{indent}end"
|
112
115
|
return [prefix, body, suffix].join("\n")
|
113
|
-
end
|
116
|
+
end
|
114
117
|
end
|
115
|
-
|
118
|
+
|
116
119
|
class Configuration
|
117
120
|
attr_reader :name, :statements
|
118
121
|
|
@@ -127,14 +130,11 @@ module Fig
|
|
127
130
|
|
128
131
|
def commands
|
129
132
|
result = statements.select { |statement| statement.is_a?(Command) }
|
130
|
-
# if result.empty?
|
131
|
-
# raise "No commands found for config: #{@name}"
|
132
|
-
# end
|
133
133
|
result
|
134
134
|
end
|
135
135
|
|
136
136
|
def unparse(indent)
|
137
|
-
unparse_statements(indent, "config #{@name}", @statements,
|
137
|
+
unparse_statements(indent, "config #{@name}", @statements, 'end')
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
@@ -145,7 +145,7 @@ module Fig
|
|
145
145
|
@name = name
|
146
146
|
@value = value
|
147
147
|
end
|
148
|
-
|
148
|
+
|
149
149
|
def unparse(indent)
|
150
150
|
"#{indent}append #{name}=#{value}"
|
151
151
|
end
|
@@ -158,7 +158,7 @@ module Fig
|
|
158
158
|
@name = name
|
159
159
|
@value = value
|
160
160
|
end
|
161
|
-
|
161
|
+
|
162
162
|
def unparse(indent)
|
163
163
|
"#{indent}set #{name}=#{value}"
|
164
164
|
end
|
@@ -175,7 +175,7 @@ module Fig
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def unparse(indent)
|
178
|
-
descriptor =
|
178
|
+
descriptor = ''
|
179
179
|
descriptor += @package_name if @package_name
|
180
180
|
descriptor += "/#{@version_name}" if @version_name
|
181
181
|
descriptor += ":#{@config_name}" if @config_name
|
@@ -188,14 +188,14 @@ module Fig
|
|
188
188
|
|
189
189
|
class Override
|
190
190
|
attr_reader :package_name, :version_name
|
191
|
-
|
191
|
+
|
192
192
|
def initialize(package_name, version_name)
|
193
193
|
@package_name = package_name
|
194
194
|
@version_name = version_name
|
195
195
|
end
|
196
196
|
|
197
197
|
def unparse()
|
198
|
-
return
|
198
|
+
return ' override ' + @package_name + '/' + @version_name
|
199
199
|
end
|
200
200
|
end
|
201
201
|
|
@@ -207,7 +207,7 @@ module Fig
|
|
207
207
|
end
|
208
208
|
|
209
209
|
def unparse(indent)
|
210
|
-
|
210
|
+
%Q<#{indent}command "#{@command}">
|
211
211
|
end
|
212
212
|
end
|
213
213
|
|
@@ -216,5 +216,5 @@ end
|
|
216
216
|
def unparse_statements(indent, prefix, statements, suffix)
|
217
217
|
body = @statements.map { |statement| statement.unparse(indent+' ') }.join("\n")
|
218
218
|
return ["\n#{indent}#{prefix}", body, "#{indent}#{suffix}"].join("\n")
|
219
|
-
end
|
219
|
+
end
|
220
220
|
|