fig 0.1.35 → 0.1.36

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/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