fig 0.1.12 → 0.1.13
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +12 -0
- data/bin/fig +13 -9
- data/lib/fig/environment.rb +16 -2
- data/lib/fig/grammar.treetop +1 -1
- data/lib/fig/os.rb +125 -38
- data/lib/fig/repository.rb +2 -2
- data/lib/fig/windows.rb +46 -0
- data/spec/fig_spec.rb +21 -4
- data/spec/win_spec.rb +21 -0
- metadata +35 -3
data/README.md
CHANGED
@@ -19,6 +19,18 @@ Fig can be installed via rubygems. The gems are hosted at [Gemcutter](http://gem
|
|
19
19
|
$ gem install gemcutter
|
20
20
|
$ gem tumble
|
21
21
|
|
22
|
+
Fig also depends on a third-party library named, [libarchive](http://libarchive.rubyforge.org/). Libarchive is easily available
|
23
|
+
via most package management systems on Linux, FreeBSD, and OS X. Libarchive versions greater than 2.6.0 are preferred. If you are on Windows, the gem will install the libarchive binaries for you.
|
24
|
+
|
25
|
+
[Linux - Debian / Ubuntu]
|
26
|
+
apt-get libarchive-dev
|
27
|
+
|
28
|
+
[Linux - Red Hat / CentOS]
|
29
|
+
yum install libarchive-devel
|
30
|
+
|
31
|
+
[OS X - MacPorts]
|
32
|
+
port install libarchive
|
33
|
+
|
22
34
|
Then you can install fig:
|
23
35
|
|
24
36
|
$ gem install fig
|
data/bin/fig
CHANGED
@@ -10,6 +10,7 @@ require 'fig/environment'
|
|
10
10
|
require 'fig/repository'
|
11
11
|
require 'fig/os'
|
12
12
|
require 'fig/parser'
|
13
|
+
require 'fig/windows'
|
13
14
|
|
14
15
|
include Fig
|
15
16
|
|
@@ -118,23 +119,27 @@ end
|
|
118
119
|
|
119
120
|
if input
|
120
121
|
package = Parser.new.parse_package(nil, nil, ".", input)
|
122
|
+
direct_retrieves=[]
|
121
123
|
if options[:retrieve]
|
122
124
|
package.retrieves.each do |var, path|
|
123
|
-
|
125
|
+
if var =~ /^@([^\/]+)(.*)/
|
126
|
+
direct_retrieves << [$1, $2, path]
|
127
|
+
else
|
128
|
+
env.add_retrieve(var, path)
|
129
|
+
end
|
124
130
|
end
|
125
131
|
end
|
126
132
|
unless options[:publish] || options[:list]
|
127
133
|
env.register_package(package)
|
128
134
|
env.apply_config(package, options[:config])
|
135
|
+
direct_retrieves.each do |info|
|
136
|
+
env.direct_retrieve(info[0], info[1], info[2])
|
137
|
+
end
|
129
138
|
end
|
130
139
|
else
|
131
140
|
package = Package.new(nil, nil, ".", [])
|
132
141
|
end
|
133
142
|
|
134
|
-
def shell_exec(cmd)
|
135
|
-
exec(ENV['SHELL'], '-c', cmd.join(' '))
|
136
|
-
end
|
137
|
-
|
138
143
|
if options[:publish]
|
139
144
|
raise "Unexpected arguments: #{argv.join(' ')}" if !argv.empty?
|
140
145
|
package_name, config_name, version_name = parse_descriptor(options[:publish])
|
@@ -154,12 +159,11 @@ elsif options[:echo]
|
|
154
159
|
puts env[options[:echo]]
|
155
160
|
elsif shell_command
|
156
161
|
argv.shift
|
157
|
-
env.execute_shell(shell_command) { |cmd| shell_exec cmd }
|
162
|
+
env.execute_shell(shell_command) { |cmd| os.shell_exec cmd }
|
158
163
|
elsif argv[0]
|
159
164
|
package_name, config_name, version_name = parse_descriptor(argv.shift)
|
160
165
|
env.include_config(package, package_name, config_name, version_name)
|
161
|
-
env.execute_config(package, package_name, config_name, nil, argv) { |cmd| shell_exec cmd }
|
166
|
+
env.execute_config(package, package_name, config_name, nil, argv) { |cmd| os.shell_exec cmd }
|
162
167
|
elsif input
|
163
|
-
env.execute_config(package, nil, options[:config], nil, argv) { |cmd| shell_exec cmd }
|
168
|
+
env.execute_config(package, nil, options[:config], nil, argv) { |cmd| os.shell_exec cmd }
|
164
169
|
end
|
165
|
-
|
data/lib/fig/environment.rb
CHANGED
@@ -74,6 +74,12 @@ module Fig
|
|
74
74
|
apply_config(package, config_name || "default")
|
75
75
|
end
|
76
76
|
|
77
|
+
def direct_retrieve(package_name, source_path, target_path)
|
78
|
+
package = lookup_package(package_name, nil)
|
79
|
+
FileUtils.mkdir_p(target_path)
|
80
|
+
FileUtils.cp_r(File.join(package.directory, source_path, '.'), target_path)
|
81
|
+
end
|
82
|
+
|
77
83
|
private
|
78
84
|
|
79
85
|
def set_variable(base_package, name, value)
|
@@ -82,7 +88,16 @@ module Fig
|
|
82
88
|
|
83
89
|
def append_variable(base_package, name, value)
|
84
90
|
value = expand_value(base_package, name, value)
|
85
|
-
|
91
|
+
# TODO: converting all environment variables to upcase is not a robust
|
92
|
+
# comparison. It also assumes all env vars will be in upcase
|
93
|
+
# in package.fig
|
94
|
+
prev = nil
|
95
|
+
@variables.each do |key, val|
|
96
|
+
if key.upcase == name.upcase
|
97
|
+
name = key
|
98
|
+
prev = val
|
99
|
+
end
|
100
|
+
end
|
86
101
|
if prev
|
87
102
|
@variables[name] = value + File::PATH_SEPARATOR + prev
|
88
103
|
else
|
@@ -100,7 +115,6 @@ module Fig
|
|
100
115
|
end
|
101
116
|
end
|
102
117
|
|
103
|
-
|
104
118
|
def lookup_package(package_name, version_name)
|
105
119
|
package = @packages[package_name]
|
106
120
|
if package.nil?
|
data/lib/fig/grammar.treetop
CHANGED
@@ -32,7 +32,7 @@ grammar Fig
|
|
32
32
|
end
|
33
33
|
|
34
34
|
rule retrieve
|
35
|
-
"retrieve" ws var:[a-zA-Z0-9]+ "->" path:[a-zA-Z0-9/\.-\[\]]+ ws {
|
35
|
+
"retrieve" ws var:[@a-zA-Z0-9/\._]+ "->" path:[a-zA-Z0-9/\.-\[\]]+ ws {
|
36
36
|
def to_package_statement
|
37
37
|
Retrieve.new(var.text_value, path.text_value)
|
38
38
|
end
|
data/lib/fig/os.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
# Must specify absolute path of ::Archive when using
|
3
|
+
# this module to avoid conflicts with Fig::Package::Archive
|
4
|
+
require 'libarchive_ruby'
|
2
5
|
require 'uri'
|
3
6
|
require 'net/http'
|
7
|
+
require 'net/ssh'
|
8
|
+
require 'net/sftp'
|
4
9
|
require 'tempfile'
|
5
10
|
|
6
11
|
module Fig
|
@@ -80,35 +85,9 @@ module Fig
|
|
80
85
|
when "ssh"
|
81
86
|
# TODO need better way to do conditional download
|
82
87
|
# timestamp = `ssh #{uri.user + '@' if uri.user}#{uri.host} "ruby -e 'puts File.mtime(\\"#{uri.path}\\").to_i'"`.to_i
|
83
|
-
out = nil
|
84
88
|
timestamp = File.exist?(path) ? File.mtime(path).to_i : 0
|
85
|
-
|
86
|
-
|
87
|
-
first = true
|
88
|
-
while bytes = io.read(4096)
|
89
|
-
if first
|
90
|
-
$stderr.puts "downloading #{url}"
|
91
|
-
first = false
|
92
|
-
end
|
93
|
-
tempfile << bytes
|
94
|
-
end
|
95
|
-
end
|
96
|
-
tempfile.close
|
97
|
-
case $?.exitstatus
|
98
|
-
when NOT_MODIFIED
|
99
|
-
tempfile.delete
|
100
|
-
return false
|
101
|
-
when NOT_FOUND
|
102
|
-
tempfile.delete
|
103
|
-
raise "File not found: #{uri}"
|
104
|
-
when SUCCESS
|
105
|
-
FileUtils.mv(tempfile.path, path)
|
106
|
-
return true
|
107
|
-
else
|
108
|
-
tempfile.delete
|
109
|
-
$stderr.puts "Unable to download file: #{$?.exitstatus}"
|
110
|
-
exit 1
|
111
|
-
end
|
89
|
+
cmd = "fig-download #{timestamp} #{uri.path}"
|
90
|
+
ssh_download(uri.user, uri.host, path, cmd)
|
112
91
|
else
|
113
92
|
raise "Unknown protocol: #{url}"
|
114
93
|
end
|
@@ -126,13 +105,13 @@ module Fig
|
|
126
105
|
download(url, path)
|
127
106
|
case basename
|
128
107
|
when /\.tar\.gz$/
|
129
|
-
|
108
|
+
unpack_archive(dir, path)
|
130
109
|
when /\.tgz$/
|
131
|
-
|
110
|
+
unpack_archive(dir, path)
|
132
111
|
when /\.tar\.bz2$/
|
133
|
-
|
112
|
+
unpack_archive(dir, path)
|
134
113
|
when /\.zip$/
|
135
|
-
|
114
|
+
unpack_archive(dir, path)
|
136
115
|
else
|
137
116
|
raise "Unknown archive type: #{basename}"
|
138
117
|
end
|
@@ -143,9 +122,7 @@ module Fig
|
|
143
122
|
uri = URI.parse(remote_file)
|
144
123
|
case uri.scheme
|
145
124
|
when "ssh"
|
146
|
-
|
147
|
-
cmd = "mkdir -p #{dir} && cat > #{uri.path}"
|
148
|
-
fail unless system "cat #{local_file} | ssh #{uri.user + '@' if uri.user}#{uri.host} '#{cmd}'"
|
125
|
+
ssh_upload(uri.user, uri.host, local_file, remote_file)
|
149
126
|
when "ftp"
|
150
127
|
# fail unless system "curl -T #{local_file} --create-dirs --ftp-create-dirs #{remote_file}"
|
151
128
|
require 'net/ftp'
|
@@ -172,8 +149,6 @@ module Fig
|
|
172
149
|
end
|
173
150
|
ftp.putbinaryfile(local_file)
|
174
151
|
end
|
175
|
-
else
|
176
|
-
fail unless system "curl -p -T #{local_file} --create-dirs --ftp-create-dirs #{remote_file}"
|
177
152
|
end
|
178
153
|
end
|
179
154
|
|
@@ -184,16 +159,128 @@ module Fig
|
|
184
159
|
|
185
160
|
def exec(dir,command)
|
186
161
|
Dir.chdir(dir) { raise "Command failed" unless system command }
|
187
|
-
|
162
|
+
end
|
188
163
|
|
189
164
|
def copy(source, target)
|
190
165
|
FileUtils.mkdir_p(File.dirname(target))
|
191
166
|
FileUtils.copy_file(source, target)
|
192
167
|
target
|
193
168
|
end
|
169
|
+
|
170
|
+
def move_file(dir, from, to)
|
171
|
+
Dir.chdir(dir) { FileUtils.mv(from, to, :force => true) }
|
172
|
+
end
|
194
173
|
|
195
174
|
def log_info(msg)
|
196
175
|
puts msg
|
197
176
|
end
|
177
|
+
|
178
|
+
# Expects files_to_archive as an Array of filenames.
|
179
|
+
def create_archive(archive_name, files_to_archive)
|
180
|
+
# TODO: Need to verify files_to_archive exists.
|
181
|
+
::Archive.write_open_filename(archive_name, ::Archive::COMPRESSION_GZIP, ::Archive::FORMAT_TAR) do |ar|
|
182
|
+
files_to_archive.each do |fn|
|
183
|
+
ar.new_entry do |entry|
|
184
|
+
entry.copy_stat(fn)
|
185
|
+
entry.pathname = fn
|
186
|
+
ar.write_header(entry)
|
187
|
+
if !entry.directory?
|
188
|
+
ar.write_data(open(fn) {|f| f.read })
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# This method can handle the following archive types:
|
196
|
+
# .tar.bz2
|
197
|
+
# .tar.gz
|
198
|
+
# .tgz
|
199
|
+
# .zip
|
200
|
+
def unpack_archive(dir, file)
|
201
|
+
Dir.chdir(dir) do
|
202
|
+
::Archive.read_open_filename(file) do |ar|
|
203
|
+
while entry = ar.next_header
|
204
|
+
ar.extract(entry)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def self.windows?
|
211
|
+
Config::CONFIG['host_os'] =~ /mswin/
|
212
|
+
end
|
213
|
+
|
214
|
+
def self.unix?
|
215
|
+
!windows?
|
216
|
+
end
|
217
|
+
|
218
|
+
def shell_exec(cmd)
|
219
|
+
if OS.windows?
|
220
|
+
Windows.shell_exec_windows(cmd)
|
221
|
+
else
|
222
|
+
shell_exec_unix(cmd)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
private
|
227
|
+
|
228
|
+
def shell_exec_unix(cmd)
|
229
|
+
Kernel.exec(ENV['SHELL'], '-c', cmd.join(' '))
|
230
|
+
end
|
231
|
+
|
232
|
+
def shell_exec_windows(cmd)
|
233
|
+
#command = ["C:/WINDOWS/system32/cmd.exe", "/C", "call"] + cmd
|
234
|
+
command = ["cmd.exe", "/C"] + cmd
|
235
|
+
command = command.join(' ')
|
236
|
+
Kernel.exec(command)
|
237
|
+
end
|
238
|
+
|
239
|
+
# path = The local path the file should be downloaded to.
|
240
|
+
# cmd = The command to be run on the remote host.
|
241
|
+
def ssh_download(user, host, path, cmd)
|
242
|
+
return_code = nil
|
243
|
+
tempfile = Tempfile.new("tmp")
|
244
|
+
Net::SSH.start(host, user) do |ssh|
|
245
|
+
ssh.open_channel do |channel|
|
246
|
+
channel.exec(cmd)
|
247
|
+
channel.on_data() { |ch, data| tempfile << data }
|
248
|
+
channel.on_extended_data() { |ch, type, data| $stderr.puts "SSH Download ERROR: #{data}" }
|
249
|
+
channel.on_request("exit-status") { |ch, request|
|
250
|
+
return_code = request.read_long
|
251
|
+
}
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
tempfile.close()
|
256
|
+
|
257
|
+
case return_code
|
258
|
+
when NOT_MODIFIED
|
259
|
+
tempfile.delete
|
260
|
+
return false
|
261
|
+
when NOT_FOUND
|
262
|
+
tempfile.delete
|
263
|
+
raise "File not found: #{uri}"
|
264
|
+
when SUCCESS
|
265
|
+
FileUtils.mv(tempfile.path, path)
|
266
|
+
return true
|
267
|
+
else
|
268
|
+
tempfile.delete
|
269
|
+
$stderr.puts "Unable to download file: #{return_code}"
|
270
|
+
exit 1
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def ssh_upload(user, host, local_file, remote_file)
|
275
|
+
uri = URI.parse(remote_file)
|
276
|
+
dir = uri.path[0, uri.path.rindex('/')]
|
277
|
+
Net::SSH.start(host, user) do |ssh|
|
278
|
+
ssh.exec!("mkdir -p #{dir}")
|
279
|
+
end
|
280
|
+
Net::SFTP.start(host, user) do |sftp|
|
281
|
+
sftp.upload!(local_file, uri.path)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
198
285
|
end
|
199
286
|
end
|
data/lib/fig/repository.rb
CHANGED
@@ -86,7 +86,7 @@ module Fig
|
|
86
86
|
end
|
87
87
|
if resources.size > 0
|
88
88
|
file = "resources.tar.gz"
|
89
|
-
file
|
89
|
+
@os.create_archive(file, resources.join(' '))
|
90
90
|
new_package_statements.unshift(Archive.new(file))
|
91
91
|
at_exit { File.delete(file) }
|
92
92
|
end
|
@@ -179,7 +179,7 @@ module Fig
|
|
179
179
|
@os.clear_directory(local_dir)
|
180
180
|
# some packages contain no files, only a fig file.
|
181
181
|
if not (package.archive_urls.empty? && package.resource_urls.empty?)
|
182
|
-
|
182
|
+
FileUtils.mv(Dir.glob(File.join(temp_dir, "*")), local_dir)
|
183
183
|
end
|
184
184
|
write_local_package(package_name, version_name, package)
|
185
185
|
rescue
|
data/lib/fig/windows.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Keeping Windows-specific implementation details here.
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
# I don't know how to set environment variables so that a sub-shell will
|
7
|
+
# be able to use them. Therefore, I'm punting, and creating a batch script
|
8
|
+
# on the fly to run a user supplied command.
|
9
|
+
|
10
|
+
module Fig
|
11
|
+
class Windows
|
12
|
+
|
13
|
+
BATCH_SCRIPT_TEMPLATE = <<EOF
|
14
|
+
@echo off
|
15
|
+
% ENV.each do |k,v|
|
16
|
+
set <%= k %>=<%= v %>
|
17
|
+
% end
|
18
|
+
|
19
|
+
cmd /C <%= command %>
|
20
|
+
EOF
|
21
|
+
|
22
|
+
|
23
|
+
def self.with_generated_batch_script(cmd)
|
24
|
+
command = cmd.join(' ')
|
25
|
+
template = ERB.new(BATCH_SCRIPT_TEMPLATE, 0, "%")
|
26
|
+
output = template.result(binding)
|
27
|
+
begin
|
28
|
+
tf = File.new("C:/tmp/fig_command.bat", "w")
|
29
|
+
FileUtils.chmod(0755, tf.path)
|
30
|
+
File.open(tf.path, "w") do |fh|
|
31
|
+
fh.puts output
|
32
|
+
end
|
33
|
+
tf.close
|
34
|
+
yield tf.path
|
35
|
+
ensure
|
36
|
+
# tf.delete
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.shell_exec_windows(cmd)
|
41
|
+
with_generated_batch_script(cmd) do |f|
|
42
|
+
Kernel.exec(f)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/fig_spec.rb
CHANGED
@@ -1,17 +1,34 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
4
|
+
require 'fig/os'
|
5
5
|
require 'fileutils'
|
6
6
|
|
7
|
+
class Popen
|
8
|
+
if Fig::OS.windows?
|
9
|
+
require 'win32/open3'
|
10
|
+
def self.popen(*cmd)
|
11
|
+
Open3.popen3(*cmd) { |stdin,stdout,stderr|
|
12
|
+
yield stdin, stdout, stderr
|
13
|
+
}
|
14
|
+
end
|
15
|
+
else
|
16
|
+
require 'open4'
|
17
|
+
def self.popen(*cmd)
|
18
|
+
Open4::popen4(*cmd) { |pid, stdin, stdout, stderr|
|
19
|
+
yield stdin, stdout, stderr
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
7
25
|
FIG_HOME = File.expand_path(File.dirname(__FILE__) + '/../tmp/fighome')
|
8
26
|
FileUtils.mkdir_p(FIG_HOME)
|
9
27
|
ENV['FIG_HOME'] = FIG_HOME
|
10
28
|
|
11
29
|
FIG_REMOTE_DIR = File.expand_path(File.dirname(__FILE__) + '/../tmp/remote')
|
12
30
|
FileUtils.mkdir_p(FIG_REMOTE_DIR)
|
13
|
-
ENV['FIG_REMOTE_URL'] = "ssh
|
14
|
-
puts ENV['FIG_REMOTE_URL']
|
31
|
+
ENV['FIG_REMOTE_URL'] = "ssh://#{ENV['USER']}@localhost#{FIG_REMOTE_DIR}"
|
15
32
|
|
16
33
|
FIG_EXE = File.expand_path(File.dirname(__FILE__) + '/../bin/fig')
|
17
34
|
|
@@ -19,7 +36,7 @@ def fig(args, input=nil)
|
|
19
36
|
args = "--file - #{args}" if input
|
20
37
|
out = nil
|
21
38
|
err = nil
|
22
|
-
|
39
|
+
Popen.popen("#{FIG_EXE} #{args}") do |stdin, stdout, stderr|
|
23
40
|
if input
|
24
41
|
stdin.puts input
|
25
42
|
stdin.close
|
data/spec/win_spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'fig/os'
|
3
|
+
require 'fig/windows'
|
4
|
+
|
5
|
+
|
6
|
+
# Only run on Windows...
|
7
|
+
if Fig::OS.windows?
|
8
|
+
describe "Fig on Windows" do
|
9
|
+
it "batch script should exist" do
|
10
|
+
Fig::Windows.with_generated_batch_script(["echo", "Hello World"]) do |filename|
|
11
|
+
File.exist?(filename).should == true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "batch script should say 'Hello World' when executed" do
|
16
|
+
Fig::Windows.with_generated_batch_script(["echo", "Hello World"]) do |filename|
|
17
|
+
%x[#{filename}].should == "Hello World\n"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fig
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Foemmel
|
@@ -9,9 +9,39 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-18 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: libarchive
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.1.1
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: net-ssh
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.15
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: net-sftp
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.0.2
|
44
|
+
version:
|
15
45
|
- !ruby/object:Gem::Dependency
|
16
46
|
name: polyglot
|
17
47
|
type: :runtime
|
@@ -73,6 +103,7 @@ files:
|
|
73
103
|
- lib/fig/package.rb
|
74
104
|
- lib/fig/parser.rb
|
75
105
|
- lib/fig/repository.rb
|
106
|
+
- lib/fig/windows.rb
|
76
107
|
- LICENSE
|
77
108
|
- README.md
|
78
109
|
has_rdoc: true
|
@@ -104,5 +135,6 @@ signing_key:
|
|
104
135
|
specification_version: 3
|
105
136
|
summary: Fig is a utility for configuring environments and managing dependencies across a team of developers..
|
106
137
|
test_files:
|
107
|
-
- spec/spec_helper.rb
|
108
138
|
- spec/fig_spec.rb
|
139
|
+
- spec/spec_helper.rb
|
140
|
+
- spec/win_spec.rb
|