fig 2.0.0.pre.alpha.4 → 2.0.0.pre.alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fig/spec_utils.rb +312 -0
  3. data/lib/fig/version.rb +1 -1
  4. data/spec/application_configuration_spec.rb +73 -0
  5. data/spec/command/clean_spec.rb +62 -0
  6. data/spec/command/command_line_vs_package_spec.rb +32 -0
  7. data/spec/command/dump_package_definition_spec.rb +104 -0
  8. data/spec/command/environment_variables_spec.rb +62 -0
  9. data/spec/command/grammar_asset_spec.rb +391 -0
  10. data/spec/command/grammar_command_spec.rb +88 -0
  11. data/spec/command/grammar_environment_variable_spec.rb +384 -0
  12. data/spec/command/grammar_retrieve_spec.rb +74 -0
  13. data/spec/command/grammar_spec.rb +87 -0
  14. data/spec/command/grammar_spec_helper.rb +23 -0
  15. data/spec/command/include_file_spec.rb +73 -0
  16. data/spec/command/listing_spec.rb +1574 -0
  17. data/spec/command/miscellaneous_spec.rb +145 -0
  18. data/spec/command/publish_local_and_updates_spec.rb +32 -0
  19. data/spec/command/publishing_retrieval_spec.rb +423 -0
  20. data/spec/command/publishing_spec.rb +596 -0
  21. data/spec/command/running_commands_spec.rb +354 -0
  22. data/spec/command/suppress_includes_spec.rb +65 -0
  23. data/spec/command/suppress_warning_include_statement_missing_version_spec.rb +134 -0
  24. data/spec/command/update_lock_response_spec.rb +47 -0
  25. data/spec/command/usage_errors_spec.rb +481 -0
  26. data/spec/command_options_spec.rb +184 -0
  27. data/spec/command_spec.rb +49 -0
  28. data/spec/deparser/v1_spec.rb +64 -0
  29. data/spec/environment_variables_spec.rb +91 -0
  30. data/spec/figrc_spec.rb +144 -0
  31. data/spec/parser_spec.rb +398 -0
  32. data/spec/repository_spec.rb +117 -0
  33. data/spec/runtime_environment_spec.rb +357 -0
  34. data/spec/spec_helper.rb +1 -0
  35. data/spec/split_repo_url_spec.rb +190 -0
  36. data/spec/statement/asset_spec.rb +203 -0
  37. data/spec/statement/configuration_spec.rb +41 -0
  38. data/spec/support/formatters/seed_spitter.rb +12 -0
  39. data/spec/working_directory_maintainer_spec.rb +102 -0
  40. metadata +42 -5
@@ -0,0 +1,117 @@
1
+ # coding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
+
5
+ require 'fig/application_configuration'
6
+ require 'fig/command/options'
7
+ require 'fig/file_not_found_error'
8
+ require 'fig/logging'
9
+ require 'fig/package_descriptor'
10
+ require 'fig/repository'
11
+ require 'fig/repository_error'
12
+ require 'fig/statement/configuration'
13
+ require 'fig/statement/path'
14
+
15
+ def create_local_repository()
16
+ application_config = Fig::ApplicationConfiguration.new()
17
+ application_config.base_whitelisted_url = FIG_DOWNLOAD_URL
18
+ application_config.remote_download_url = FIG_DOWNLOAD_URL
19
+ application_config.remote_upload_url = FIG_UPLOAD_URL
20
+
21
+ parser = Fig::Parser.new(application_config, false)
22
+
23
+ repository = Fig::Repository.new(
24
+ application_config,
25
+ Fig::Command::Options.new,
26
+ Fig::OperatingSystem.new(nil),
27
+ FIG_HOME,
28
+ FIG_DOWNLOAD_URL,
29
+ FIG_UPLOAD_URL,
30
+ parser,
31
+ [], # publish listeners
32
+ )
33
+ repository.update_if_missing
34
+
35
+ return repository
36
+ end
37
+
38
+ def generate_package_statements
39
+ parsed_name, parsed_value = Fig::Statement::Path.parse_name_value 'FOO=bar'
40
+ path_statement =
41
+ Fig::Statement::Path.new(nil, nil, parsed_name, parsed_value)
42
+ configuration_statement =
43
+ Fig::Statement::Configuration.new(
44
+ nil, nil, Fig::Package::DEFAULT_CONFIG, [path_statement]
45
+ )
46
+
47
+ package_statements = [configuration_statement]
48
+
49
+ return package_statements
50
+ end
51
+
52
+ describe 'Repository' do
53
+ before(:each) do
54
+ clean_up_test_environment
55
+ set_up_test_environment
56
+ end
57
+
58
+ it 'cleans a package from the repository' do
59
+ repository = create_local_repository
60
+
61
+ repository.list_packages.include?('foo/1.0.0').should be false
62
+
63
+ package_statements = generate_package_statements
64
+
65
+ descriptor = Fig::PackageDescriptor.new('foo', '1.0.0', nil)
66
+ repository.publish_package(package_statements, descriptor, false, nil, false)
67
+
68
+ repository.list_packages.include?('foo/1.0.0').should be true
69
+
70
+ repository.clean(descriptor)
71
+
72
+ repository.list_packages.include?('foo/1.0.0').should be false
73
+ end
74
+
75
+ describe 'handles errors while installing packages' do
76
+ it %q<that don't exist> do
77
+ repository = create_local_repository
78
+
79
+ repository.stub(:install_package) do
80
+ raise Fig::FileNotFoundError.new('test FileNotFoundError', 'fake path')
81
+ end
82
+ # Evil knowledge of implementation:
83
+ repository.instance_variable_set(:@updating_package_definition, true)
84
+
85
+ Fig::Logging.should_receive(:fatal).with(
86
+ /package.*package-name.*not found/i
87
+ )
88
+
89
+ descriptor = Fig::PackageDescriptor.new(
90
+ 'package-name', 'package-version', nil
91
+ )
92
+ expect {
93
+ repository.get_package(descriptor)
94
+ }.to raise_error(Fig::RepositoryError)
95
+ end
96
+
97
+ it 'that have some sort of installation issue' do
98
+ repository = create_local_repository
99
+
100
+ exception_message = 'test StandardError'
101
+ repository.stub(:install_package) do
102
+ raise StandardError.new(exception_message)
103
+ end
104
+
105
+ Fig::Logging.should_receive(:fatal).with(
106
+ %r<install of package-name/package-version failed.*#{exception_message}>i
107
+ )
108
+
109
+ descriptor = Fig::PackageDescriptor.new(
110
+ 'package-name', 'package-version', nil
111
+ )
112
+ expect {
113
+ repository.get_package(descriptor)
114
+ }.to raise_error(Fig::RepositoryError)
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,357 @@
1
+ # coding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
+
5
+ require 'fig/environment_variables/case_sensitive'
6
+ require 'fig/package'
7
+ require 'fig/package_descriptor'
8
+ require 'fig/parser'
9
+ require 'fig/runtime_environment'
10
+ require 'fig/statement/command'
11
+ require 'fig/statement/configuration'
12
+ require 'fig/statement/retrieve'
13
+ require 'fig/statement/set'
14
+
15
+ DEPENDED_UPON_PACKAGE_NAME = 'depended_upon'
16
+
17
+ def standard_package_version(name)
18
+ return "#{name}-version"
19
+ end
20
+
21
+ def new_example_package(environment, name, extra_statements, variable_value)
22
+ statements = extra_statements +
23
+ [
24
+ Fig::Statement::Configuration.new(
25
+ nil, nil, Fig::Package::DEFAULT_CONFIG, []
26
+ )
27
+ ]
28
+
29
+ package =
30
+ Fig::Package.new(
31
+ name,
32
+ standard_package_version(name),
33
+ nil,
34
+ nil,
35
+ "#{name}-directory",
36
+ "#{name}-directory",
37
+ statements,
38
+ false,
39
+ )
40
+
41
+ environment.register_package(package)
42
+
43
+ # Kind of a cheat: we're creating a "set" statement that isn't in a "config"
44
+ # block and then shoving it through the RuntimeEnvironment directly.
45
+ set_statement = new_example_set_statement(name, variable_value)
46
+ environment.apply_config_statement(package, set_statement, nil, 0)
47
+
48
+ return package
49
+ end
50
+
51
+ def new_example_environment(variable_value = 'whatever', retrieve_vars = {})
52
+ maintainer_double = double('working directory maintainer')
53
+ maintainer_double.stub(:switch_to_package_version)
54
+ maintainer_double.stub(:retrieve)
55
+ environment =
56
+ Fig::RuntimeEnvironment.new(
57
+ nil,
58
+ Fig::Parser.new(nil, false),
59
+ false,
60
+ Fig::EnvironmentVariables::CaseSensitive.new({'FOO' => 'bar'}),
61
+ maintainer_double
62
+ )
63
+
64
+ if retrieve_vars
65
+ retrieve_vars.each do |name, path|
66
+ tokenized_path = Fig::Statement::Retrieve.tokenize_path path
67
+ environment.add_retrieve(
68
+ Fig::Statement::Retrieve.new(nil, nil, name, tokenized_path)
69
+ )
70
+ end
71
+ end
72
+
73
+ depended_upon_package_version =
74
+ standard_package_version(DEPENDED_UPON_PACKAGE_NAME)
75
+ new_example_package(
76
+ environment, DEPENDED_UPON_PACKAGE_NAME, [], variable_value
77
+ )
78
+
79
+ %w< one two three >.each do
80
+ |package_name|
81
+
82
+ extra_statements = [
83
+ Fig::Statement::Include.new(
84
+ nil,
85
+ nil,
86
+ Fig::PackageDescriptor.parse(
87
+ "#{DEPENDED_UPON_PACKAGE_NAME}/#{depended_upon_package_version}"
88
+ ),
89
+ nil,
90
+ package_name
91
+ )
92
+ ]
93
+ new_example_package(
94
+ environment, package_name, extra_statements, variable_value
95
+ )
96
+ end
97
+
98
+ command = Fig::Statement::Command.new(
99
+ nil,
100
+ nil,
101
+ [
102
+ Fig::Statement::Command.validate_and_process_escapes_in_argument(
103
+ 'echo foo'
104
+ )
105
+ ]
106
+ )
107
+ environment.register_package(
108
+ Fig::Package.new(
109
+ 'has_command', 'version', nil, nil, 'directory', 'directory',
110
+ [
111
+ Fig::Statement::Configuration.new(
112
+ nil,
113
+ nil,
114
+ Fig::Package::DEFAULT_CONFIG,
115
+ [command]
116
+ )
117
+ ],
118
+ false,
119
+ )
120
+ )
121
+
122
+ return environment
123
+ end
124
+
125
+ def new_example_set_statement(name, value)
126
+ parsed_name, parsed_value =
127
+ Fig::Statement::Set.parse_name_value("WHATEVER_#{name.upcase}=#{value}") do
128
+ |description|
129
+
130
+ raise StandardError.new(
131
+ %Q<Never should have gotten here. Description: "#{description}">
132
+ )
133
+ end
134
+
135
+ return Fig::Statement::Set.new(nil, nil, parsed_name, parsed_value)
136
+ end
137
+
138
+ def substitute_command(command)
139
+ environment = new_example_environment
140
+ base_package =
141
+ Fig::Package.new(
142
+ 'test-package',
143
+ 'test-version',
144
+ nil,
145
+ nil,
146
+ 'test-directory',
147
+ 'test-directory',
148
+ [],
149
+ false,
150
+ )
151
+
152
+ tokenized_command = command.map {
153
+ |argument|
154
+
155
+ Fig::Statement::Command.validate_and_process_escapes_in_argument(argument) {
156
+ |error_description| raise error_description
157
+ }
158
+ }
159
+
160
+ substituted_command = nil
161
+ environment.expand_command_line(base_package, nil, nil, tokenized_command) {
162
+ |command_line|
163
+ substituted_command = command_line
164
+ }
165
+
166
+ return substituted_command
167
+ end
168
+
169
+ def generate_shell_variable_expansions
170
+ variable_arguments = %w<WHATEVER_ONE WHATEVER_TWO WHATEVER_THREE>
171
+ return variable_arguments.map do |var_arg|
172
+ Fig::OperatingSystem.wrap_variable_name_with_shell_expansion(var_arg)
173
+ end
174
+ end
175
+
176
+ def substitute_variable(variable_value, retrieve_vars = {})
177
+ environment = new_example_environment(variable_value, retrieve_vars)
178
+ base_package =
179
+ Fig::Package.new(
180
+ 'test-package',
181
+ 'test-version',
182
+ nil,
183
+ nil,
184
+ 'test-directory',
185
+ 'test-directory',
186
+ [],
187
+ false,
188
+ )
189
+
190
+ output = nil
191
+ variables = generate_shell_variable_expansions
192
+ environment.expand_command_line(base_package, nil, nil, []) {
193
+ # No space between the closing curly of an interpolation and the double
194
+ # ampersand due to the way that echo works on MS Windows.
195
+ output =
196
+ %x[echo #{variables[0]}&& echo #{variables[1]}&& echo #{variables[2]}]
197
+ }
198
+
199
+ return output
200
+ end
201
+
202
+ describe 'RuntimeEnvironment' do
203
+ before(:all) do
204
+ set_up_test_environment()
205
+ end
206
+
207
+ it 'can hand back a variable' do
208
+ environment = new_example_environment
209
+
210
+ environment['FOO'].should == 'bar'
211
+ end
212
+
213
+ describe 'package name substitution in commands' do
214
+ it 'can replace bare names' do
215
+ substituted_command = substitute_command %w< @one >
216
+
217
+ substituted_command.should == %w< one-directory >
218
+ end
219
+
220
+ it 'can replace prefixed names' do
221
+ substituted_command = substitute_command %w< something@one >
222
+
223
+ substituted_command.should == %w< somethingone-directory >
224
+ end
225
+
226
+ it 'can replace multiple names in a single argument' do
227
+ substituted_command = substitute_command %w< @one@two@three >
228
+
229
+ substituted_command.should == %w< one-directorytwo-directorythree-directory >
230
+ end
231
+
232
+ it 'can replace names in multiple arguments' do
233
+ substituted_command = substitute_command %w< @one @two >
234
+
235
+ substituted_command.should == %w< one-directory two-directory >
236
+ end
237
+
238
+ it 'can handle simple escaped names' do
239
+ substituted_command = substitute_command %w< \@one\@two >
240
+
241
+ substituted_command.should == %w< @one@two >
242
+ end
243
+
244
+ it 'can replace name after an escaped name' do
245
+ substituted_command = substitute_command %w< \@one@two >
246
+
247
+ substituted_command.should == %w< @onetwo-directory >
248
+ end
249
+
250
+ it 'can handle escaped backslash' do
251
+ substituted_command = substitute_command %w< bar\\\\foo >
252
+
253
+ substituted_command.should == %w< bar\\foo >
254
+ end
255
+
256
+ it 'can handle escaped backslash in front of @' do
257
+ substituted_command = substitute_command %w< bar\\\\@one >
258
+
259
+ substituted_command.should == %w< bar\\one-directory >
260
+ end
261
+
262
+ it 'can handle escaped backslash in front of escaped @' do
263
+ substituted_command = substitute_command %w< bar\\\\\\@one >
264
+
265
+ substituted_command.should == %w< bar\\@one >
266
+ end
267
+
268
+ it 'complains about bad escapes' do
269
+ expect {
270
+ # Grrr, Ruby syntax: that's three backslashes followed by "f"
271
+ substitute_command %w< bar\\\\\\foo >
272
+ }.to raise_error(/bad escape/i)
273
+ end
274
+ end
275
+
276
+ describe 'package name substitution in variables' do
277
+ it 'does basic @ substitution' do
278
+ output = substitute_variable('@/foobie')
279
+
280
+ output.should ==
281
+ "one-directory/foobie\ntwo-directory/foobie\nthree-directory/foobie\n"
282
+ end
283
+
284
+ it 'does @ escaping' do
285
+ output = substitute_variable('\\@@/foobie')
286
+
287
+ output.should ==
288
+ "@one-directory/foobie\n@two-directory/foobie\n@three-directory/foobie\n"
289
+ end
290
+
291
+ it 'does retrieve variables [package] substitution' do
292
+ retrieve_vars = {
293
+ 'WHATEVER_ONE' => 'foo.[package].bar.[package].baz',
294
+ 'WHATEVER_TWO' => 'foo.[package].bar.[package].baz',
295
+ 'WHATEVER_THREE' => 'foo.[package].bar.[package].baz'
296
+ }
297
+ output = substitute_variable(FIG_FILE_GUARANTEED_TO_EXIST, retrieve_vars)
298
+
299
+ destination = File.basename(FIG_FILE_GUARANTEED_TO_EXIST)
300
+ output.should ==
301
+ "foo.one.bar.one.baz/#{destination}\nfoo.two.bar.two.baz/#{destination}\nfoo.three.bar.three.baz/#{destination}\n"
302
+ end
303
+
304
+ it 'truncates before //' do
305
+ if FIG_FILE_GUARANTEED_TO_EXIST !~
306
+ %r<
307
+ \A
308
+ (.+ [^/]) # Maximally at least two charcters not ending in a slash.
309
+ (
310
+ (?: / [^/]+ ){2} # Slash followed by maximally non-slash, twice.
311
+ )
312
+ \z
313
+ >x
314
+ fail "Test assumes that FIG_FILE_GUARANTEED_TO_EXIST (#{FIG_FILE_GUARANTEED_TO_EXIST}) has at least two parent directories."
315
+ end
316
+ base_path = $1
317
+ to_be_preserved = $2 # Note that this will have a leading slash...
318
+
319
+ # ... which means that this will have two slashes in it.
320
+ mangled_path = "#{base_path}/#{to_be_preserved}"
321
+
322
+ retrieve_vars = {
323
+ # Just checking that double slashes aren't mangled in the retrieves.
324
+ 'WHATEVER_ONE' => 'foo.[package].//./bar.[package].baz',
325
+ # No WHATEVER_TWO here means that the value should pass through
326
+ # unmolested.
327
+ 'WHATEVER_THREE' => 'phoo.//.bhar'
328
+ }
329
+ output = substitute_variable(mangled_path, retrieve_vars)
330
+
331
+ output.should == \
332
+ "foo.one.//./bar.one.baz#{to_be_preserved}\n" + # WHATEVER_ONE
333
+ "#{mangled_path}\n" + # WHATEVER_TWO
334
+ "phoo.//.bhar#{to_be_preserved}\n" # WHATEVER_THREE
335
+ end
336
+ end
337
+
338
+ describe 'command expansion' do
339
+ it 'issues an error when attempting to expand a command statement from a config which contains no command' do
340
+ environment = new_example_environment(FIG_FILE_GUARANTEED_TO_EXIST)
341
+ expect {
342
+ environment.expand_command_statement_from_config(
343
+ nil, nil, Fig::PackageDescriptor.new('one', nil, nil), nil
344
+ )
345
+ }.to raise_error(Fig::UserInputError)
346
+ end
347
+
348
+ it 'expands a command statement successfully' do
349
+ environment = new_example_environment(FIG_FILE_GUARANTEED_TO_EXIST)
350
+ received_command = nil
351
+ environment.expand_command_statement_from_config(
352
+ nil, nil, Fig::PackageDescriptor.new('has_command', nil, nil), []
353
+ ) { |command| received_command = command }
354
+ received_command.should == ['echo foo']
355
+ end
356
+ end
357
+ end
@@ -0,0 +1 @@
1
+ require 'fig/spec_utils.rb'
@@ -0,0 +1,190 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ require 'fileutils'
4
+ require 'tmpdir'
5
+
6
+ require 'fig/command/package_loader'
7
+ require 'fig/operating_system'
8
+ require 'fig/repository'
9
+
10
+ describe "Split repository URL behavior" do
11
+ context 'starting with a clean home and remote repository' do
12
+ before(:each) do
13
+ clean_up_test_environment
14
+ set_up_test_environment
15
+ cleanup_home_and_remote
16
+ end
17
+
18
+ def create_test_repos(unified: false)
19
+ # Name separate download and upload directories
20
+ download_dir = File.join(FIG_SPEC_BASE_DIRECTORY, 'download-repo')
21
+ upload_dir = File.join(FIG_SPEC_BASE_DIRECTORY, 'upload-repo')
22
+
23
+ # Clean up any existing directories
24
+ FileUtils.rm_rf(download_dir)
25
+ FileUtils.rm_rf(upload_dir)
26
+
27
+ # Create the "repositories" based on whether we want unified or not
28
+ FileUtils.mkdir_p(upload_dir)
29
+ FileUtils.mkdir_p(File.join(upload_dir, Fig::Repository::METADATA_SUBDIRECTORY))
30
+
31
+ if unified
32
+ FileUtils.ln_s(upload_dir, download_dir)
33
+ else
34
+ FileUtils.mkdir_p(download_dir)
35
+ FileUtils.mkdir_p(File.join(download_dir, Fig::Repository::METADATA_SUBDIRECTORY))
36
+ end
37
+
38
+ return download_dir, upload_dir
39
+ end
40
+
41
+ it "(distinct repos) publishes to upload URL and downloads from download URL" do
42
+ # Create separate repos
43
+ download_dir, upload_dir = create_test_repos
44
+ download_url = "file://#{download_dir}"
45
+ upload_url = "file://#{upload_dir}"
46
+
47
+ # Set up environment for this test
48
+ ENV['FIG_DOWNLOAD_URL'] = download_url
49
+ ENV['FIG_UPLOAD_URL'] = upload_url
50
+
51
+ # Create a simple package
52
+ input = <<-END
53
+ config default
54
+ set FOO=BAR
55
+ end
56
+ END
57
+
58
+ # Create a package with publish-only
59
+ out, err, exit_code =
60
+ fig(%w<--publish simple/1.2.3>, input, :no_raise_on_error => true)
61
+ exit_code.should == 0
62
+
63
+ # Check that package exists in upload repo but not in download repo
64
+ upload_path = File.join(upload_dir, 'simple', '1.2.3', Fig::Repository::PACKAGE_FILE_IN_REPO)
65
+ download_path = File.join(download_dir, 'simple', '1.2.3', Fig::Repository::PACKAGE_FILE_IN_REPO)
66
+
67
+ File.exist?(upload_path).should be true
68
+ File.exist?(download_path).should be false
69
+ end
70
+
71
+ it "(unified repos) publishes to upload URL and downloads from download URL" do
72
+ # Create separate repos
73
+ download_dir, upload_dir = create_test_repos(unified: true)
74
+ download_url = "file://#{download_dir}"
75
+ upload_url = "file://#{upload_dir}"
76
+
77
+ # Set up environment for this test
78
+ ENV['FIG_DOWNLOAD_URL'] = download_url
79
+ ENV['FIG_UPLOAD_URL'] = upload_url
80
+
81
+ download_url.should_not == upload_url
82
+ FileTest.symlink?(download_dir).should be true
83
+ FileTest.identical?(upload_dir, download_dir)
84
+
85
+ # Create a simple package
86
+ input = <<-END
87
+ config default
88
+ set FOO=BAR
89
+ end
90
+ END
91
+
92
+ # Create a package with publish-only
93
+ out, err, exit_code =
94
+ fig(%w<--publish simple/1.2.3>, input, :no_raise_on_error => true)
95
+ exit_code.should == 0
96
+
97
+ # Check that package exists in upload repo AND in download repo
98
+ upload_path = File.join(upload_dir, 'simple', '1.2.3', Fig::Repository::PACKAGE_FILE_IN_REPO)
99
+ download_path = File.join(download_dir, 'simple', '1.2.3', Fig::Repository::PACKAGE_FILE_IN_REPO)
100
+
101
+ File.exist?(upload_path).should be true
102
+ File.exist?(download_path).should be true
103
+ end
104
+ it "warns when FIG_REMOTE_URL is set alongside the new URLs" do
105
+ # Set up conflicting environment
106
+ ENV['FIG_REMOTE_URL'] = "file:///some/path"
107
+ ENV['FIG_DOWNLOAD_URL'] = "file:///download/path"
108
+ ENV['FIG_UPLOAD_URL'] = "file:///upload/path"
109
+
110
+ # We need to mock the $stderr output since that's where the warning goes
111
+ # Capture original stderr and redirect to a StringIO
112
+ original_stderr = $stderr
113
+ $stderr = StringIO.new
114
+
115
+ # Create a minimal default.fig file for the test to work
116
+ File.open('default.fig', 'w') { |f| f.puts "config default\nend" }
117
+
118
+ # Use Fig::FigRC directly to trigger the warning
119
+ Fig::FigRC.find(nil, ENV['FIG_DOWNLOAD_URL'], ENV['FIG_UPLOAD_URL'],
120
+ Fig::OperatingSystem.new(false),
121
+ FIG_HOME)
122
+
123
+ # Get the captured output and restore stderr
124
+ err_output = $stderr.string
125
+ $stderr = original_stderr
126
+
127
+ # Check that the warning was emitted
128
+ err_output.should =~ /WARNING: FIG_REMOTE_URL is set but will be ignored/
129
+
130
+ # Clean up
131
+ File.unlink('default.fig') if File.exist?('default.fig')
132
+ end
133
+
134
+ it "fails when FIG_REMOTE_URL is set but new URLs are missing" do
135
+ # Set up invalid environment
136
+ ENV['FIG_REMOTE_URL'] = "file:///some/path"
137
+ ENV.delete('FIG_DOWNLOAD_URL')
138
+ ENV.delete('FIG_UPLOAD_URL')
139
+
140
+ # Create a minimal default.fig file for the test to work
141
+ File.open('default.fig', 'w') { |f| f.puts "config default\nend" }
142
+
143
+ # Try to use fig with remote operation, should get error
144
+ out, err, exit_code = fig(%w<--update>, :no_raise_on_error => true)
145
+
146
+ # Should fail with clear error message
147
+ exit_code.should_not == 0
148
+ err.should =~ /FIG_REMOTE_URL is set but FIG_DOWNLOAD_URL and\/or FIG_UPLOAD_URL are missing/
149
+
150
+ # Clean up
151
+ File.unlink('default.fig') if File.exist?('default.fig')
152
+ end
153
+
154
+ it "fails with helpful message when required URL is missing" do
155
+ # Make sure we have no URLs set
156
+ ENV.delete('FIG_REMOTE_URL')
157
+ ENV.delete('FIG_DOWNLOAD_URL')
158
+ ENV.delete('FIG_UPLOAD_URL')
159
+
160
+ # Publishing without upload URL
161
+ input = <<-END
162
+ config default
163
+ set FOO=BAR
164
+ end
165
+ END
166
+
167
+ out, err, exit_code = fig(%w<--publish simple/1.2.3>, input, :no_raise_on_error => true)
168
+ exit_code.should_not == 0
169
+ err.should =~ /Must set FIG_UPLOAD_URL/
170
+
171
+ # Consuming without download URL
172
+ out, err, exit_code = fig(%w<--update>, :no_raise_on_error => true)
173
+ exit_code.should_not == 0
174
+ err.should =~ /Must set FIG_DOWNLOAD_URL/
175
+ end
176
+ end
177
+
178
+ after(:all) do
179
+ # Clean up and restore environment
180
+ download_dir = File.join(FIG_SPEC_BASE_DIRECTORY, 'download-repo')
181
+ upload_dir = File.join(FIG_SPEC_BASE_DIRECTORY, 'upload-repo')
182
+ FileUtils.rm_rf(download_dir) if Dir.exist?(download_dir)
183
+ FileUtils.rm_rf(upload_dir) if Dir.exist?(upload_dir)
184
+
185
+ # Restore environment variables to default test values
186
+ ENV['FIG_DOWNLOAD_URL'] = FIG_DOWNLOAD_URL
187
+ ENV['FIG_UPLOAD_URL'] = FIG_UPLOAD_URL
188
+ ENV.delete('FIG_REMOTE_URL')
189
+ end
190
+ end