fig 0.1.35 → 0.1.36

Sign up to get free protection for your applications and to get access to all the features.
data/bin/fig CHANGED
@@ -5,6 +5,7 @@ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
5
5
  require 'rubygems'
6
6
  require 'net/ftp'
7
7
 
8
+ require 'fig/retriever'
8
9
  require 'fig/options'
9
10
  require 'fig/environment'
10
11
  require 'fig/repository'
@@ -59,16 +60,18 @@ end
59
60
 
60
61
  os = OS.new(options[:login])
61
62
  repos = Repository.new(os, File.expand_path(File.join(options[:home], 'repos')), remote_url, remote_user, options[:update], options[:update_if_missing])
62
- env = Environment.new(os, repos, vars)
63
+ retriever = Retriever.new(".")
64
+ at_exit { retriever.save }
65
+ env = Environment.new(os, repos, vars, retriever)
63
66
 
64
67
  options[:modifiers].each do |modifier|
65
- env.apply_config_statement(nil, modifier)
68
+ env.apply_config_statement(nil, modifier, nil)
66
69
  end
67
70
 
68
- if File.exist?(".fig")
69
- $stderr.puts "The '.fig' file is deprecated. Please rename to 'package.fig'"
70
- exit 1
71
- end
71
+ #if File.exist?(".fig")
72
+ # $stderr.puts "The '.fig' file is deprecated. Please rename to 'package.fig'"
73
+ # exit 1
74
+ #end
72
75
 
73
76
  DEFAULT_FIG_FILE = 'package.fig'
74
77
 
@@ -131,7 +134,7 @@ if input
131
134
  end
132
135
  unless options[:publish] || options[:list] || options[:publish_local]
133
136
  env.register_package(package)
134
- env.apply_config(package, options[:config])
137
+ env.apply_config(package, options[:config], nil)
135
138
  direct_retrieves.each do |info|
136
139
  env.direct_retrieve(info[0], info[1], info[2])
137
140
  end
@@ -0,0 +1,37 @@
1
+ class Backtrace
2
+ def initialize(parent, package_name, version_name, config_name)
3
+ @parent = parent
4
+ @package_name = package_name
5
+ @version_name = version_name
6
+ @config_name = config_name || "default"
7
+ end
8
+
9
+ def collect(stack)
10
+ if @parent
11
+ @parent.collect(stack)
12
+ end
13
+ elem = ""
14
+ if @package_name
15
+ elem = @package_name
16
+ end
17
+ if @version_name
18
+ elem += "/" + @version_name
19
+ end
20
+ if @config_name
21
+ elem += ":" + @config_name
22
+ end
23
+ stack << elem
24
+ end
25
+
26
+ def dump(out)
27
+ stack = []
28
+ collect(stack)
29
+ i=0
30
+ for elem in stack
31
+ indent=""
32
+ i.times { indent += " " }
33
+ out.puts indent+elem
34
+ i += 1
35
+ end
36
+ end
37
+ end
@@ -1,3 +1,5 @@
1
+ require 'fig/backtrace'
2
+
1
3
  module Fig
2
4
 
3
5
  # This class manages the program's state, including the value of all environment
@@ -5,13 +7,14 @@ module Fig
5
7
  class Environment
6
8
  DEFAULT_VERSION_NAME = "current"
7
9
 
8
- def initialize(os, repository, variables)
10
+ def initialize(os, repository, variables, retriever)
9
11
  @os = os
10
12
  @repository = repository
11
13
  @variables = variables
12
14
  @retrieve_vars = {}
13
15
  @packages = {}
14
16
  @applied_configs = {}
17
+ @retriever = retriever
15
18
  end
16
19
 
17
20
  # Returns the value of an envirionment variable
@@ -34,12 +37,13 @@ module Fig
34
37
  @packages[name] = package
35
38
  end
36
39
 
37
- def apply_config(package, config_name)
40
+ def apply_config(package, config_name, backtrace)
38
41
  if (@applied_configs[package.package_name] ||= []).member?(config_name)
39
42
  return
40
43
  end
44
+ new_backtrace = Backtrace.new(backtrace, package.package_name, package.version_name, config_name)
41
45
  config = package[config_name]
42
- config.statements.each { |stmt| apply_config_statement(package, stmt) }
46
+ config.statements.each { |stmt| apply_config_statement(package, stmt, new_backtrace) }
43
47
  @applied_configs[package.package_name] << config_name
44
48
  end
45
49
 
@@ -50,7 +54,7 @@ module Fig
50
54
  end
51
55
 
52
56
  def execute_config(base_package, package_name, config_name, version_name, args)
53
- package = lookup_package(package_name || base_package.package_name, version_name)
57
+ package = lookup_package(package_name || base_package.package_name, version_name, Backtrace.new(nil, package_name, version_name, config_name))
54
58
  result = nil
55
59
  commands = package[config_name || "default"].commands
56
60
  with_environment do
@@ -62,14 +66,14 @@ module Fig
62
66
  result
63
67
  end
64
68
 
65
- def apply_config_statement(base_package, statement)
69
+ def apply_config_statement(base_package, statement, backtrace)
66
70
  case statement
67
71
  when Path
68
72
  append_variable(base_package, statement.name, statement.value)
69
73
  when Set
70
74
  set_variable(base_package, statement.name, statement.value)
71
75
  when Include
72
- include_config(base_package, statement.package_name, statement.config_name, statement.version_name)
76
+ include_config(base_package, statement.package_name, statement.config_name, statement.version_name, backtrace)
73
77
  when Command
74
78
  # ignore
75
79
  else
@@ -77,13 +81,14 @@ module Fig
77
81
  end
78
82
  end
79
83
 
80
- def include_config(base_package, package_name, config_name, version_name)
81
- package = lookup_package(package_name || base_package.package_name, version_name)
82
- apply_config(package, config_name || "default")
84
+ def include_config(base_package, package_name, config_name, version_name, backtrace)
85
+ new_backtrace = Backtrace.new(backtrace, package_name, version_name, config_name)
86
+ package = lookup_package(package_name || base_package.package_name, version_name, new_backtrace)
87
+ apply_config(package, config_name || "default", backtrace)
83
88
  end
84
89
 
85
90
  def direct_retrieve(package_name, source_path, target_path)
86
- package = lookup_package(package_name, nil)
91
+ package = lookup_package(package_name, nil, nil)
87
92
  FileUtils.mkdir_p(target_path)
88
93
  FileUtils.cp_r(File.join(package.directory, source_path, '.'), target_path)
89
94
  end
@@ -123,13 +128,16 @@ module Fig
123
128
  end
124
129
  end
125
130
 
126
- def lookup_package(package_name, version_name)
131
+ def lookup_package(package_name, version_name, backtrace)
127
132
  package = @packages[package_name]
128
133
  if package.nil?
129
134
  package = @repository.load_package(package_name, version_name || DEFAULT_VERSION_NAME)
135
+ package.backtrace = backtrace
130
136
  @packages[package_name] = package
131
137
  elsif version_name && version_name != package.version_name
132
138
  $stderr.puts "Version mismatch: #{package_name}"
139
+ backtrace.dump($stderr) if backtrace
140
+ package.backtrace.dump($stderr) if package.backtrace
133
141
  exit 10
134
142
  end
135
143
  package
@@ -151,7 +159,9 @@ module Fig
151
159
  target = File.join(target, File.basename(file))
152
160
  end
153
161
  end
154
- @os.copy(file, target, "retrieving")
162
+ @retriever.with_config(base_package.package_name, base_package.version_name) do
163
+ @retriever.retrieve(file, target)
164
+ end
155
165
  file = target
156
166
  end
157
167
  file
@@ -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
@@ -255,10 +255,11 @@ module Fig
255
255
  end
256
256
  end
257
257
  else
258
- if !FileUtils.uptodate?(target, [source])
258
+ if !File.exist?(target) || File.mtime(source) != File.mtime(target)
259
259
  log_info "#{msg} #{target}" if msg
260
260
  FileUtils.mkdir_p(File.dirname(target))
261
261
  FileUtils.cp(source, target)
262
+ File.utime(File.atime(source), File.mtime(source), target)
262
263
  end
263
264
  end
264
265
  end
@@ -1,14 +1,16 @@
1
1
  module Fig
2
2
  class Package
3
3
  attr_reader :package_name, :version_name, :directory, :statements
4
+ attr_accessor :backtrace
4
5
 
5
6
  def initialize(package_name, version_name, directory, statements)
6
7
  @package_name = package_name
7
8
  @version_name = version_name
8
9
  @directory = directory
9
10
  @statements = statements
11
+ @backtrace = nil
10
12
  end
11
-
13
+
12
14
  def [](config_name)
13
15
  @statements.each do |stmt|
14
16
  return stmt if stmt.is_a?(Configuration) && stmt.name == config_name
@@ -42,6 +44,10 @@ module Fig
42
44
  def ==(other)
43
45
  @package_name == other.package_name && @version_name == other.version_name && @statements.to_yaml == other.statements.to_yaml
44
46
  end
47
+
48
+ def to_s
49
+ @package_name + "/" + @version_name
50
+ end
45
51
  end
46
52
 
47
53
  class Archive
@@ -0,0 +1,107 @@
1
+ require 'ostruct'
2
+ require 'set'
3
+
4
+ # This class copies files from the project directories in ~/.fighome to the
5
+ # user's working directory. It keeps track of which files have already been copied, and which
6
+ # package/versions they came from, and deletes files as necessary to ensure that
7
+ # we never have files from two different versions of the same package in the user's
8
+ # working directory.
9
+ class Retriever
10
+ def initialize(base_dir)
11
+ @base_dir = base_dir
12
+ @configs = {}
13
+ @fig_dir = File.join(@base_dir, ".fig")
14
+
15
+ file = File.join(@fig_dir, "retrieve")
16
+ if File.exist?(file)
17
+ load(file)
18
+ end
19
+ end
20
+
21
+ def with_config(name, version)
22
+ if name and version
23
+ @config = @configs[name]
24
+ if @config && @config.version != version
25
+ @config.files.each do |relpath|
26
+ $stderr.puts "\033[31m- [#{@config.name}/#{@config.version}] #{relpath}\033[0m"
27
+ FileUtils.rm_f(File.join(@base_dir, relpath))
28
+ end
29
+ @config = nil
30
+ end
31
+ if not @config
32
+ @config = new_config(name, version)
33
+ @configs[name] = @config
34
+ end
35
+ else
36
+ @config = nil
37
+ end
38
+ yield
39
+ end
40
+
41
+ def retrieve(source, relpath)
42
+ copy(source, relpath)
43
+ end
44
+
45
+ def save
46
+ FileUtils.mkdir_p(@fig_dir)
47
+ File.open(File.join(@fig_dir, "retrieve"), 'w') do |f|
48
+ @configs.each do |name,config|
49
+ config.files.each do |target|
50
+ f << target << "=" << config.name << "/" << config.version << "\n"
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def load(file)
59
+ File.open(file).each_line do |line|
60
+ line = line.strip()
61
+ if line =~ /^(.+)=(.+)\/(.+)$/
62
+ target = $1
63
+ config_name = $2
64
+ config_version = $3
65
+ config = @configs[config_name]
66
+ if config
67
+ if config.version != config_version
68
+ raise "version mismatch in .figretrieve"
69
+ end
70
+ else
71
+ config = new_config(config_name, config_version)
72
+ @configs[config_name] = config
73
+ end
74
+ config.files << target
75
+ else
76
+ raise "parse error in #{file}: #{line}"
77
+ end
78
+ end
79
+ end
80
+
81
+ def new_config(name, version)
82
+ config = OpenStruct.new
83
+ config.name = name
84
+ config.version = version
85
+ config.files = Set.new()
86
+ return config
87
+ end
88
+
89
+ def copy(source, relpath)
90
+ target = File.join(@base_dir, relpath)
91
+ if File.directory?(source)
92
+ FileUtils.mkdir_p(target)
93
+ Dir.foreach(source) do |child|
94
+ if child != "." and child != ".."
95
+ copy(File.join(source, child), File.join(relpath, child))
96
+ end
97
+ end
98
+ else
99
+ if !File.exist?(target) || File.mtime(source) > File.mtime(target)
100
+ $stderr.puts "\033[32m+ [#{@config.name}/#{@config.version}] #{relpath}\033[0m"
101
+ FileUtils.mkdir_p(File.dirname(target))
102
+ FileUtils.cp(source, target)
103
+ end
104
+ @config.files << relpath if @config
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,331 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ require 'rubygems'
4
+ require 'fig/os'
5
+ require 'rake'
6
+ require 'fileutils'
7
+
8
+ class Popen
9
+ if Fig::OS.windows?
10
+ require 'win32/open3'
11
+ def self.popen(*cmd)
12
+ Open3.popen3(*cmd) { |stdin,stdout,stderr|
13
+ yield stdin, stdout, stderr
14
+ }
15
+ end
16
+ elsif Fig::OS.java?
17
+ require 'open3'
18
+ def self.popen(*cmd)
19
+ Open3.popen3(*cmd) { |stdin,stdout,stderr|
20
+ yield stdin, stdout, stderr
21
+ }
22
+ end
23
+ else
24
+ require 'open4'
25
+ def self.popen(*cmd)
26
+ Open4::popen4(*cmd) { |pid, stdin, stdout, stderr|
27
+ yield stdin, stdout, stderr
28
+ }
29
+ end
30
+ end
31
+ end
32
+
33
+ FIG_HOME = File.expand_path(File.dirname(__FILE__) + '/../tmp/fighome')
34
+ FileUtils.mkdir_p(FIG_HOME)
35
+ ENV['FIG_HOME'] = FIG_HOME
36
+
37
+ FIG_REMOTE_DIR = File.expand_path(File.dirname(__FILE__) + '/../tmp/remote')
38
+ FileUtils.mkdir_p(FIG_REMOTE_DIR)
39
+ ENV['FIG_REMOTE_URL'] = "ssh://#{ENV['USER']}@localhost#{FIG_REMOTE_DIR}"
40
+
41
+ FIG_EXE = File.expand_path(File.dirname(__FILE__) + '/../bin/fig')
42
+
43
+ def fig(args, input=nil)
44
+ args = "--file - #{args}" if input
45
+ out = nil
46
+ err = nil
47
+ Popen.popen("#{RUBY} #{FIG_EXE} #{args}") do |stdin, stdout, stderr|
48
+ if input
49
+ stdin.puts input
50
+ stdin.close
51
+ end
52
+ err = stderr.read.strip
53
+ out = stdout.read.strip
54
+ if err != ""
55
+ $stderr.puts err
56
+ end
57
+ end
58
+ return out, err, $?.exitstatus
59
+ end
60
+
61
+ describe "Fig" do
62
+ it "set environment variable from command line" do
63
+ fig('-s FOO=BAR -g FOO')[0].should == 'BAR'
64
+ fig('--set FOO=BAR -g FOO')[0].should == 'BAR'
65
+ end
66
+
67
+ it "set environment variable from fig file" do
68
+ input = <<-END
69
+ config default
70
+ set FOO=BAR
71
+ end
72
+ END
73
+ fig('-g FOO', input)[0].should == 'BAR'
74
+ end
75
+
76
+ it "append environment variable from command line" do
77
+ fig('-p PATH=foo -g PATH').should == ["foo#{File::PATH_SEPARATOR}#{ENV['PATH']}","",0]
78
+ end
79
+
80
+ it "append environment variable from fig file" do
81
+ input = <<-END
82
+ config default
83
+ add PATH=foo
84
+ end
85
+ END
86
+ fig('-g PATH', input).should == ["foo#{File::PATH_SEPARATOR}#{ENV['PATH']}","",0]
87
+ end
88
+
89
+ it "append empty environment variable" do
90
+ fig('-p XYZZY=foo -g XYZZY').should == ["foo","",0]
91
+ end
92
+
93
+ it "should ignore comments" do
94
+ input = <<-END
95
+ #/usr/bin/env fig
96
+
97
+ # Some comment
98
+ config default
99
+ set FOO=BAR # Another comment
100
+ end
101
+ END
102
+ fig('-g FOO', input)[0].should == 'BAR'
103
+ end
104
+
105
+ it "publish to remote repository" do
106
+ FileUtils.rm_rf(FIG_HOME)
107
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
108
+ input = <<-END
109
+ config default
110
+ set FOO=BAR
111
+ end
112
+ END
113
+ fig('--publish foo/1.2.3', input)
114
+ fail unless File.exists? FIG_HOME + "/repos/foo/1.2.3/.fig"
115
+ fail unless File.exists? FIG_REMOTE_DIR + "/foo/1.2.3/.fig"
116
+ fig('-u -i foo/1.2.3 -g FOO')[0].should == 'BAR'
117
+ end
118
+
119
+ it "publish resource to remote repository" do
120
+ FileUtils.rm_rf(FIG_HOME)
121
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
122
+ FileUtils.mkdir_p("tmp/bin")
123
+ File.open("tmp/bin/hello", "w") { |f| f << "echo bar" }
124
+ fail unless system "chmod +x tmp/bin/hello"
125
+ input = <<-END
126
+ resource tmp/bin/hello
127
+ config default
128
+ append PATH=@/tmp/bin
129
+ end
130
+ END
131
+ fig('--publish foo/1.2.3', input)
132
+ fail unless File.exists? FIG_HOME + "/repos/foo/1.2.3/.fig"
133
+ fail unless File.exists? FIG_REMOTE_DIR + "/foo/1.2.3/.fig"
134
+ fig('-u -i foo/1.2.3 -- hello')[0].should == 'bar'
135
+ end
136
+
137
+ it "publish resource to remote repository using command line" do
138
+ FileUtils.rm_rf(FIG_HOME)
139
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
140
+ FileUtils.mkdir_p("tmp/bin")
141
+ File.open("tmp/bin/hello", "w") { |f| f << "echo bar" }
142
+ fail unless system "chmod +x tmp/bin/hello"
143
+ fig('--publish foo/1.2.3 --resource tmp/bin/hello --append PATH=@/tmp/bin')
144
+ fail unless File.exists? FIG_HOME + "/repos/foo/1.2.3/.fig"
145
+ fail unless File.exists? FIG_REMOTE_DIR + "/foo/1.2.3/.fig"
146
+ fig('-u -i foo/1.2.3 -- hello')[0].should == 'bar'
147
+ end
148
+
149
+ it "refuses to overwrite existing version in remote repository without being forced" do
150
+ FileUtils.rm_rf(FIG_HOME)
151
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
152
+ input = <<-END
153
+ config default
154
+ set FOO=SHEEP
155
+ end
156
+ END
157
+ fig('--publish foo/1.2.3', input)
158
+ fail unless File.exists? FIG_HOME + "/repos/foo/1.2.3/.fig"
159
+ fail unless File.exists? FIG_REMOTE_DIR + "/foo/1.2.3/.fig"
160
+ fig('-u -i foo/1.2.3 -g FOO')[0].should == 'SHEEP'
161
+
162
+ input = <<-END
163
+ config default
164
+ set FOO=CHEESE
165
+ end
166
+ END
167
+ (out, err, exitstatus) = fig('--publish foo/1.2.3', input)
168
+ exitstatus.should == 1
169
+ fig('-u -i foo/1.2.3 -g FOO')[0].should == 'SHEEP'
170
+
171
+ (out, err, exitstatus) = fig('--publish foo/1.2.3 --force', input)
172
+ exitstatus.should == 0
173
+ fig('-u -i foo/1.2.3 -g FOO')[0].should == 'CHEESE'
174
+ end
175
+
176
+ it "publishes to the local repo only when told to" do
177
+ FileUtils.rm_rf(FIG_HOME)
178
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
179
+ FileUtils.mkdir_p("tmp/bin")
180
+ File.open("tmp/bin/hello", "w") { |f| f << "echo bar" }
181
+ fail unless system "chmod +x tmp/bin/hello"
182
+ fig('--publish-local foo/1.2.3 --resource tmp/bin/hello --append PATH=@/tmp/bin')
183
+ fail if File.exists? FIG_REMOTE_DIR + "/foo/1.2.3/.fig"
184
+ fig('-m -i foo/1.2.3 -- hello')[0].should == 'bar'
185
+ end
186
+
187
+ it "retrieve resource" do
188
+ FileUtils.rm_rf(FIG_HOME)
189
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
190
+ FileUtils.rm_rf("tmp")
191
+ FileUtils.mkdir_p("tmp/lib")
192
+ File.open("tmp/lib/hello", "w") { |f| f << "some library" }
193
+ input = <<-END
194
+ resource tmp/lib/hello
195
+ config default
196
+ append FOOPATH=@/tmp/lib/hello
197
+ end
198
+ END
199
+ fig('--publish foo/1.2.3', input)
200
+ input = <<-END
201
+ retrieve FOOPATH->tmp/lib2/[package]
202
+ config default
203
+ include foo/1.2.3
204
+ end
205
+ END
206
+ fig('-m', input)
207
+ File.read("tmp/lib2/foo/hello").should == "some library"
208
+ end
209
+
210
+ it "retrieves resource that is a directory" do
211
+ FileUtils.rm_rf(FIG_HOME)
212
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
213
+ FileUtils.rm_rf("tmp")
214
+ FileUtils.mkdir_p("tmp/lib")
215
+ File.open("tmp/lib/hello", "w") { |f| f << "some library" }
216
+ # To copy the contents of a directory, instead of the directory itself,
217
+ # use '/.' as a suffix to the directory name in 'append'.
218
+ input = <<-END
219
+ resource tmp/lib/hello
220
+ config default
221
+ append FOOPATH=@/tmp/lib/.
222
+ end
223
+ END
224
+ fig('--publish foo/1.2.3', input)
225
+ input = <<-END
226
+ retrieve FOOPATH->tmp/lib2/[package]
227
+ config default
228
+ include foo/1.2.3
229
+ end
230
+ END
231
+ fig('-m', input)
232
+ File.read("tmp/lib2/foo/hello").should == "some library"
233
+ end
234
+
235
+ it "retrieve preserves the path after '//' when copying files into your project directory" do
236
+ FileUtils.rm_rf(FIG_HOME)
237
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
238
+ FileUtils.rm_rf("tmp")
239
+ FileUtils.mkdir_p("tmp/include")
240
+ File.open("tmp/include/hello.h", "w") { |f| f << "a header file" }
241
+ File.open("tmp/include/hello2.h", "w") { |f| f << "another header file" }
242
+ input = <<-END
243
+ resource tmp/include/hello.h
244
+ resource tmp/include/hello2.h
245
+ config default
246
+ append INCLUDE=@/tmp//include/hello.h
247
+ append INCLUDE=@/tmp//include/hello2.h
248
+ end
249
+ END
250
+ fig('--publish foo/1.2.3', input)
251
+
252
+ input = <<-END
253
+ retrieve INCLUDE->tmp/include2/[package]
254
+ config default
255
+ include foo/1.2.3
256
+ end
257
+ END
258
+ fig('-u', input)
259
+
260
+ File.read("tmp/include2/foo/include/hello.h").should == "a header file"
261
+ File.read("tmp/include2/foo/include/hello2.h").should == "another header file"
262
+ end
263
+
264
+ it "package multiple resources" do
265
+ FileUtils.rm_rf(FIG_HOME)
266
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
267
+ FileUtils.rm_rf("tmp")
268
+ FileUtils.mkdir_p("tmp/lib")
269
+ File.open("tmp/lib/hello", "w") { |f| f << "some library" }
270
+ File.open("tmp/lib/hello2", "w") { |f| f << "some other library" }
271
+ input = <<-END
272
+ resource tmp/lib/hello
273
+ resource tmp/lib/hello2
274
+ config default
275
+ append FOOPATH=@/tmp/lib/hello
276
+ append FOOPATH=@/tmp/lib/hello2
277
+ end
278
+ END
279
+ fig('--publish foo/1.2.3', input)
280
+ input = <<-END
281
+ retrieve FOOPATH->tmp/lib2/[package]
282
+ config default
283
+ include foo/1.2.3
284
+ end
285
+ END
286
+ fig('-m', input)
287
+ File.read("tmp/lib2/foo/hello").should == "some library"
288
+ File.read("tmp/lib2/foo/hello2").should == "some other library"
289
+ end
290
+
291
+ it "packages multiple resources with wildcards" do
292
+ FileUtils.rm_rf(FIG_HOME)
293
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
294
+ FileUtils.rm_rf("tmp")
295
+ FileUtils.mkdir_p("tmp/lib")
296
+ File.open("tmp/lib/foo.jar", "w") { |f| f << "some library" }
297
+ File.open("tmp/lib/bar.jar", "w") { |f| f << "some other library" }
298
+ input = <<-END
299
+ resource tmp/**/*.jar
300
+ config default
301
+ append FOOPATH=@/tmp/lib/foo.jar
302
+ end
303
+ END
304
+ fig('--publish foo/1.2.3', input)
305
+ input = <<-END
306
+ retrieve FOOPATH->tmp/lib2/[package]
307
+ config default
308
+ include foo/1.2.3
309
+ end
310
+ END
311
+ fig('-m', input)
312
+ File.read("tmp/lib2/foo/foo.jar").should == "some library"
313
+ end
314
+
315
+ it "update local packages if they already exist" do
316
+ FileUtils.rm_rf(FIG_HOME)
317
+ FileUtils.rm_rf(FIG_REMOTE_DIR)
318
+ FileUtils.mkdir_p("tmp/bin")
319
+ File.open("tmp/bin/hello", "w") { |f| f << "echo sheep" }
320
+ fail unless system "chmod +x tmp/bin/hello"
321
+ fig('--publish-local foo/1.2.3 --resource tmp/bin/hello --append PATH=@/tmp/bin')
322
+ fail if File.exists? FIG_REMOTE_DIR + "/foo/1.2.3/.fig"
323
+ fig('-m -i foo/1.2.3 -- hello')[0].should == 'sheep'
324
+
325
+ File.open("tmp/bin/hello", "w") { |f| f << "echo cheese" }
326
+ fail unless system "chmod +x tmp/bin/hello"
327
+ fig('--publish-local foo/1.2.3 --resource tmp/bin/hello --append PATH=@/tmp/bin')
328
+ fail if File.exists? FIG_REMOTE_DIR + "/foo/1.2.3/.fig"
329
+ fig('-m -i foo/1.2.3 -- hello')[0].should == 'cheese'
330
+ end
331
+ end
@@ -0,0 +1,47 @@
1
+ require 'fig/retriever'
2
+
3
+ describe "Retriever" do
4
+ it "retrieves single file" do
5
+
6
+ # Set up some test files
7
+ test_dir = "tmp/retrieve-test"
8
+ FileUtils.rm_rf(test_dir)
9
+ FileUtils.mkdir_p(test_dir)
10
+
11
+ File.open("tmp/foo.txt", 'w') {|f| f << "FOO"}
12
+ File.open("tmp/bar.txt", 'w') {|f| f << "BAR"}
13
+ File.open("tmp/baz.txt", 'w') {|f| f << "BAZ"}
14
+
15
+ # Retrieve files A and B
16
+ r = Retriever.new(test_dir)
17
+ r.with_config("foo", "1.2.3") do
18
+ r.retrieve("tmp/foo.txt", "foo.txt")
19
+ r.retrieve("tmp/bar.txt", "bar.txt")
20
+ File.read(File.join(test_dir, "foo.txt")).should == "FOO"
21
+ File.read(File.join(test_dir, "bar.txt")).should == "BAR"
22
+ end
23
+
24
+ # Retrieve files B and C for a different version
25
+ r.with_config("foo", "4.5.6") do
26
+ r.retrieve("tmp/bar.txt", "bar.txt")
27
+ r.retrieve("tmp/baz.txt", "baz.txt")
28
+ File.read(File.join(test_dir, "bar.txt")).should == "BAR"
29
+ File.read(File.join(test_dir, "baz.txt")).should == "BAZ"
30
+ File.exist?(File.join(test_dir, "foo.txt")).should == false
31
+ end
32
+
33
+ # Save and reload
34
+ r.save
35
+ r = Retriever.new(test_dir)
36
+
37
+ # Switch back to original version
38
+ r.with_config("foo", "1.2.3") do
39
+ r.retrieve("tmp/foo.txt", "foo.txt")
40
+ r.retrieve("tmp/bar.txt", "bar.txt")
41
+
42
+ File.read(File.join(test_dir, "foo.txt")).should == "FOO"
43
+ File.read(File.join(test_dir, "bar.txt")).should == "BAR"
44
+ File.exist?(File.join(test_dir, "baz.txt")).should == false
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'fig'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
@@ -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,13 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fig
3
3
  version: !ruby/object:Gem::Version
4
- hash: 93
5
- prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 35
10
- version: 0.1.35
4
+ version: 0.1.36
11
5
  platform: ruby
12
6
  authors:
13
7
  - Matthew Foemmel
@@ -15,152 +9,99 @@ autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
11
 
18
- date: 2011-06-20 00:00:00 -05:00
12
+ date: 2011-09-02 00:00:00 -05:00
19
13
  default_executable:
20
14
  dependencies:
21
15
  - !ruby/object:Gem::Dependency
22
16
  name: libarchive
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
26
20
  requirements:
27
21
  - - ">="
28
22
  - !ruby/object:Gem::Version
29
- hash: 25
30
- segments:
31
- - 0
32
- - 1
33
- - 1
34
23
  version: 0.1.1
35
- type: :runtime
36
- version_requirements: *id001
24
+ version:
37
25
  - !ruby/object:Gem::Dependency
38
26
  name: net-ssh
39
- prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
41
- none: false
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
42
30
  requirements:
43
31
  - - ">="
44
32
  - !ruby/object:Gem::Version
45
- hash: 17
46
- segments:
47
- - 2
48
- - 0
49
- - 15
50
33
  version: 2.0.15
51
- type: :runtime
52
- version_requirements: *id002
34
+ version:
53
35
  - !ruby/object:Gem::Dependency
54
36
  name: net-sftp
55
- prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
57
- none: false
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
58
40
  requirements:
59
41
  - - ">="
60
42
  - !ruby/object:Gem::Version
61
- hash: 5
62
- segments:
63
- - 2
64
- - 0
65
- - 5
66
43
  version: 2.0.5
67
- type: :runtime
68
- version_requirements: *id003
44
+ version:
69
45
  - !ruby/object:Gem::Dependency
70
46
  name: net-netrc
71
- prerelease: false
72
- requirement: &id004 !ruby/object:Gem::Requirement
73
- none: false
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
74
50
  requirements:
75
51
  - - ">="
76
52
  - !ruby/object:Gem::Version
77
- hash: 19
78
- segments:
79
- - 0
80
- - 2
81
- - 2
82
53
  version: 0.2.2
83
- type: :runtime
84
- version_requirements: *id004
54
+ version:
85
55
  - !ruby/object:Gem::Dependency
86
56
  name: polyglot
87
- prerelease: false
88
- requirement: &id005 !ruby/object:Gem::Requirement
89
- none: false
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
90
60
  requirements:
91
61
  - - ">="
92
62
  - !ruby/object:Gem::Version
93
- hash: 5
94
- segments:
95
- - 0
96
- - 2
97
- - 9
98
63
  version: 0.2.9
99
- type: :runtime
100
- version_requirements: *id005
64
+ version:
101
65
  - !ruby/object:Gem::Dependency
102
66
  name: treetop
103
- prerelease: false
104
- requirement: &id006 !ruby/object:Gem::Requirement
105
- none: false
67
+ type: :runtime
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
106
70
  requirements:
107
71
  - - ">="
108
72
  - !ruby/object:Gem::Version
109
- hash: 3
110
- segments:
111
- - 1
112
- - 4
113
- - 2
114
73
  version: 1.4.2
115
- type: :runtime
116
- version_requirements: *id006
74
+ version:
117
75
  - !ruby/object:Gem::Dependency
118
76
  name: highline
119
- prerelease: false
120
- requirement: &id007 !ruby/object:Gem::Requirement
121
- none: false
77
+ type: :runtime
78
+ version_requirement:
79
+ version_requirements: !ruby/object:Gem::Requirement
122
80
  requirements:
123
81
  - - ">="
124
82
  - !ruby/object:Gem::Version
125
- hash: 11
126
- segments:
127
- - 1
128
- - 6
129
- - 2
130
83
  version: 1.6.2
131
- type: :runtime
132
- version_requirements: *id007
84
+ version:
133
85
  - !ruby/object:Gem::Dependency
134
86
  name: rspec
135
- prerelease: false
136
- requirement: &id008 !ruby/object:Gem::Requirement
137
- none: false
87
+ type: :development
88
+ version_requirement:
89
+ version_requirements: !ruby/object:Gem::Requirement
138
90
  requirements:
139
91
  - - ~>
140
92
  - !ruby/object:Gem::Version
141
- hash: 9
142
- segments:
143
- - 1
144
- - 3
145
93
  version: "1.3"
146
- type: :development
147
- version_requirements: *id008
94
+ version:
148
95
  - !ruby/object:Gem::Dependency
149
96
  name: open4
150
- prerelease: false
151
- requirement: &id009 !ruby/object:Gem::Requirement
152
- none: false
97
+ type: :development
98
+ version_requirement:
99
+ version_requirements: !ruby/object:Gem::Requirement
153
100
  requirements:
154
101
  - - ">="
155
102
  - !ruby/object:Gem::Version
156
- hash: 21
157
- segments:
158
- - 1
159
- - 0
160
- - 1
161
103
  version: 1.0.1
162
- type: :development
163
- version_requirements: *id009
104
+ version:
164
105
  description: Fig is a utility for configuring environments and managing dependencies across a team of developers. You give it a list of packages and a shell command to run; it creates an environment that includes those packages, then executes the shell command in it (the caller's environment is not affected).
165
106
  email: git@foemmel.com
166
107
  executables:
@@ -175,6 +116,7 @@ files:
175
116
  - bin/fig
176
117
  - bin/fig-download
177
118
  - lib/fig.rb
119
+ - lib/fig/backtrace.rb
178
120
  - lib/fig/environment.rb
179
121
  - lib/fig/grammar.treetop
180
122
  - lib/fig/options.rb
@@ -182,6 +124,7 @@ files:
182
124
  - lib/fig/package.rb
183
125
  - lib/fig/parser.rb
184
126
  - lib/fig/repository.rb
127
+ - lib/fig/retriever.rb
185
128
  - lib/fig/windows.rb
186
129
  - LICENSE
187
130
  - README.md
@@ -190,34 +133,31 @@ homepage: http://github.com/mfoemmel/fig
190
133
  licenses: []
191
134
 
192
135
  post_install_message:
193
- rdoc_options: []
194
-
136
+ rdoc_options:
137
+ - --charset=UTF-8
195
138
  require_paths:
196
139
  - lib
197
140
  required_ruby_version: !ruby/object:Gem::Requirement
198
- none: false
199
141
  requirements:
200
142
  - - ">="
201
143
  - !ruby/object:Gem::Version
202
- hash: 3
203
- segments:
204
- - 0
205
144
  version: "0"
145
+ version:
206
146
  required_rubygems_version: !ruby/object:Gem::Requirement
207
- none: false
208
147
  requirements:
209
148
  - - ">="
210
149
  - !ruby/object:Gem::Version
211
- hash: 3
212
- segments:
213
- - 0
214
150
  version: "0"
151
+ version:
215
152
  requirements: []
216
153
 
217
154
  rubyforge_project:
218
- rubygems_version: 1.4.2
155
+ rubygems_version: 1.3.5
219
156
  signing_key:
220
157
  specification_version: 3
221
158
  summary: Fig is a utility for configuring environments and managing dependencies across a team of developers..
222
- test_files: []
223
-
159
+ test_files:
160
+ - spec/fig_spec.rb
161
+ - spec/retriever_spec.rb
162
+ - spec/spec_helper.rb
163
+ - spec/win_spec.rb