fig18 0.1.39 → 0.1.40

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.
@@ -0,0 +1,52 @@
1
+
2
+ module Fig
3
+ class ApplicationConfiguration
4
+ def initialize(remote_repository_url)
5
+ @data = []
6
+ @remote_repository_url = remote_repository_url
7
+ clear_cached_data
8
+ end
9
+
10
+ def ensure_url_whitelist_initialized()
11
+ return if not @whitelist.nil?
12
+ whitelist = self['url_whitelist']
13
+ if whitelist.nil?
14
+ @whitelist = []
15
+ else
16
+ @whitelist = [@remote_repository_url, whitelist].flatten
17
+ end
18
+ end
19
+
20
+ def [](key)
21
+ @data.each do |dataset|
22
+ if dataset.has_key?(key)
23
+ return dataset[key]
24
+ end
25
+ end
26
+ return nil
27
+ end
28
+
29
+ def push_dataset(dataset)
30
+ @data.push(dataset)
31
+ end
32
+
33
+ def unshift_dataset(dataset)
34
+ @data.unshift(dataset)
35
+ end
36
+
37
+ # after push_dataset or unshift_dataset, call clear_cached, and lazy initialize as far as the list of things to exclude
38
+
39
+ def clear_cached_data()
40
+ @whitelist = nil
41
+ end
42
+
43
+ def url_access_allowed?(url)
44
+ ensure_url_whitelist_initialized
45
+ return true if @whitelist.empty?
46
+ @whitelist.each do |allowed_url|
47
+ return true if url.match(/\A#{Regexp.quote(allowed_url)}\b/)
48
+ end
49
+ return false
50
+ end
51
+ end
52
+ end
data/lib/fig/backtrace.rb CHANGED
@@ -5,7 +5,7 @@ class Backtrace
5
5
  @parent = parent
6
6
  @package_name = package_name
7
7
  @version_name = version_name
8
- @config_name = config_name || "default"
8
+ @config_name = config_name || 'default'
9
9
  @overrides = {}
10
10
  end
11
11
 
@@ -13,15 +13,15 @@ class Backtrace
13
13
  if @parent
14
14
  @parent.collect(stack)
15
15
  end
16
- elem = ""
16
+ elem = ''
17
17
  if @package_name
18
18
  elem = @package_name
19
19
  end
20
20
  if @version_name
21
- elem += "/" + @version_name
21
+ elem += '/' + @version_name
22
22
  end
23
23
  if @config_name
24
- elem += ":" + @config_name
24
+ elem += ':' + @config_name
25
25
  end
26
26
  stack << elem
27
27
  end
@@ -41,8 +41,8 @@ class Backtrace
41
41
  collect(stack)
42
42
  i=0
43
43
  for elem in stack
44
- indent=""
45
- i.times { indent += " " }
44
+ indent=''
45
+ i.times { indent += ' ' }
46
46
  out.puts indent+elem
47
47
  i += 1
48
48
  end
@@ -0,0 +1,15 @@
1
+ require 'fig/userinputerror'
2
+
3
+ module Fig
4
+ # Could not determine some kind of information from a configuration file,
5
+ # whether .figrc, log4r, package.fig, etc.
6
+ class ConfigFileError < UserInputError
7
+ def initialize(message, file)
8
+ super(message)
9
+
10
+ @file = file
11
+
12
+ return
13
+ end
14
+ end
15
+ end
@@ -1,11 +1,14 @@
1
+ require 'stringio'
2
+
1
3
  require 'fig/backtrace'
4
+ require 'fig/logging'
5
+ require 'fig/repositoryerror'
2
6
 
3
7
  module Fig
4
-
5
- # This class manages the program's state, including the value of all environment
6
- # variables, and which packages have already been applied
8
+ # This class manages the program's state, including the value of all
9
+ # environment variables, and which packages have already been applied.
7
10
  class Environment
8
- DEFAULT_VERSION_NAME = "current"
11
+ DEFAULT_VERSION_NAME = 'current'
9
12
 
10
13
  def initialize(os, repository, variables, retriever)
11
14
  @os = os
@@ -22,8 +25,8 @@ module Fig
22
25
  @variables[name]
23
26
  end
24
27
 
25
- # Indicates that the values from a particular envrionment variable path should
26
- # be copied to a local directory
28
+ # Indicates that the values from a particular envrionment variable path
29
+
27
30
  def add_retrieve(name, path)
28
31
  @retrieve_vars[name] = path
29
32
  end
@@ -31,8 +34,8 @@ module Fig
31
34
  def register_package(package)
32
35
  name = package.package_name
33
36
  if @packages[name]
34
- $stderr.puts "Package already exists with name: #{name}"
35
- exit 10
37
+ Fig::Logging.fatal %Q<There is already a package with the name "#{name}".>
38
+ raise RepositoryError.new
36
39
  end
37
40
  @packages[name] = package
38
41
  end
@@ -41,7 +44,7 @@ module Fig
41
44
  if (@applied_configs[package.package_name] ||= []).member?(config_name)
42
45
  return
43
46
  end
44
- new_backtrace = backtrace #Backtrace.new(backtrace, package.package_name, package.version_name, config_name)
47
+ new_backtrace = backtrace
45
48
 
46
49
  config = package[config_name]
47
50
  config.statements.each { |stmt| apply_config_statement(package, stmt, new_backtrace) }
@@ -57,11 +60,11 @@ module Fig
57
60
  def execute_config(base_package, package_name, config_name, version_name, args)
58
61
  package = lookup_package(package_name || base_package.package_name, version_name, Backtrace.new(nil, package_name, version_name, config_name))
59
62
  result = nil
60
- commands = package[config_name || "default"].commands
63
+ commands = package[config_name || 'default'].commands
61
64
  with_environment do
62
- # todo nil check
65
+ # TODO nil check
63
66
  commands.each do |command|
64
- result = yield expand_arg("#{command.command} #{args.join(' ')}").gsub("@",package.directory).split(" ")
67
+ result = yield expand_arg("#{command.command} #{args.join(' ')}").gsub('@',package.directory).split(' ')
65
68
  end
66
69
  end
67
70
  result
@@ -83,7 +86,7 @@ module Fig
83
86
  end
84
87
 
85
88
  def include_config(base_package, package_name, config_name, version_name, overrides, backtrace)
86
- # Check to see if this include has been overridden
89
+ # Check to see if this include has been overridden.
87
90
  if backtrace
88
91
  override = backtrace.get_override(package_name || base_package.package_name)
89
92
  if override
@@ -95,7 +98,7 @@ module Fig
95
98
  new_backtrace.add_override(override.package_name, override.version_name)
96
99
  end
97
100
  package = lookup_package(package_name || base_package.package_name, version_name, new_backtrace)
98
- apply_config(package, config_name || "default", new_backtrace)
101
+ apply_config(package, config_name || 'default', new_backtrace)
99
102
  end
100
103
 
101
104
  def direct_retrieve(package_name, source_path, target_path)
@@ -104,7 +107,7 @@ module Fig
104
107
  FileUtils.cp_r(File.join(package.directory, source_path, '.'), target_path)
105
108
  end
106
109
 
107
- private
110
+ private
108
111
 
109
112
  def set_variable(base_package, name, value)
110
113
  @variables[name] = expand_value(base_package, name, value)
@@ -146,10 +149,14 @@ module Fig
146
149
  package.backtrace = backtrace
147
150
  @packages[package_name] = package
148
151
  elsif version_name && version_name != package.version_name
149
- $stderr.puts "Version mismatch: #{package_name}"
150
- backtrace.dump($stderr) if backtrace
151
- package.backtrace.dump($stderr) if package.backtrace
152
- exit 10
152
+ string_handle = StringIO.new
153
+ backtrace.dump(string_handle) if backtrace
154
+ package.backtrace.dump(string_handle) if package.backtrace
155
+ stacktrace = string_handle.to_s
156
+ Fig::Logging.fatal \
157
+ "Version mismatch: #{package_name}" \
158
+ + stacktrace.empty? ? '' : "\n#{stacktrace}"
159
+ raise RepositoryError.new
153
160
  end
154
161
  package
155
162
  end
@@ -159,18 +166,31 @@ module Fig
159
166
  return value unless base_package && base_package.package_name
160
167
  file = value.gsub(/\@/, base_package.directory)
161
168
  if @retrieve_vars.member?(name)
162
- # A '//' in the source file's path tells us to preserve path information
163
- # after the '//' when doing a retrieve.
169
+ # A '//' in the source file's path tells us to preserve path
170
+ # information after the '//' when doing a retrieve.
164
171
  if file.split('//').size > 1
165
172
  preserved_path = file.split('//').last
166
- target = File.join(@retrieve_vars[name].gsub(/\[package\]/, base_package.package_name), preserved_path)
173
+ target = File.join(
174
+ @retrieve_vars[name].gsub(
175
+ /\[package\]/,
176
+ base_package.package_name
177
+ ),
178
+ preserved_path
179
+ )
167
180
  else
168
- target = File.join(@retrieve_vars[name].gsub(/\[package\]/, base_package.package_name))
181
+ target = File.join(
182
+ @retrieve_vars[name].gsub(
183
+ /\[package\]/,
184
+ base_package.package_name
185
+ )
186
+ )
169
187
  if not File.directory?(file)
170
188
  target = File.join(target, File.basename(file))
171
189
  end
172
190
  end
173
- @retriever.with_config(base_package.package_name, base_package.version_name) do
191
+ @retriever.with_package_config(
192
+ base_package.package_name, base_package.version_name
193
+ ) do
174
194
  @retriever.retrieve(file, target)
175
195
  end
176
196
  file = target
@@ -182,8 +202,8 @@ module Fig
182
202
  arg.gsub(/\@([a-zA-Z0-9\-\.]+)/) do |match|
183
203
  package = @packages[$1]
184
204
  if package.nil?
185
- $stderr.puts "Package not found: #{$1}"
186
- exit 10
205
+ Fig::Logging.fatal "Package not found: #{$1}"
206
+ raise RepositoryError.new
187
207
  end
188
208
  package.directory
189
209
  end
data/lib/fig/figrc.rb ADDED
@@ -0,0 +1,105 @@
1
+ require 'json'
2
+
3
+ require 'fig/applicationconfiguration'
4
+ require 'fig/configfileerror'
5
+ require 'fig/os'
6
+
7
+ REPOSITORY_CONFIGURATION = '_meta/figrc'
8
+
9
+ module Fig
10
+ class FigRC
11
+ def self.find(
12
+ override_path, repository_url, login, fig_home, disable_figrc = false
13
+ )
14
+ configuration = ApplicationConfiguration.new(repository_url)
15
+
16
+ handle_override_configuration(configuration, override_path)
17
+ handle_figrc(configuration) if not disable_figrc
18
+ handle_repository_configuration(
19
+ configuration, repository_url, login, fig_home
20
+ )
21
+
22
+ return configuration
23
+ end
24
+
25
+ private
26
+
27
+ def self.handle_override_configuration(configuration, override_path)
28
+ begin
29
+ if not override_path.nil?
30
+ configuration.push_dataset(
31
+ JSON.parse(File::open(override_path).read)
32
+ )
33
+ end
34
+ rescue JSON::ParserError => exception
35
+ translate_parse_error(exception, override_path)
36
+ end
37
+
38
+ return
39
+ end
40
+
41
+ def self.handle_figrc(configuration)
42
+ user_figrc_path = File.expand_path('~/.figrc')
43
+ return if not File.exists? user_figrc_path
44
+
45
+ begin
46
+ configuration.push_dataset(
47
+ JSON.parse(File::open(user_figrc_path).read)
48
+ )
49
+ rescue JSON::ParserError => exception
50
+ translate_parse_error(exception, user_figrc_path)
51
+ end
52
+
53
+ return
54
+ end
55
+
56
+ def self.handle_repository_configuration(
57
+ configuration, repository_url, login, fig_home
58
+ )
59
+ return if repository_url.nil?
60
+
61
+ figrc_url = "#{repository_url}/#{REPOSITORY_CONFIGURATION}"
62
+ repo_figrc_path =
63
+ File.expand_path(File.join(fig_home, REPOSITORY_CONFIGURATION))
64
+
65
+ os = OS.new(login)
66
+
67
+ repo_config_exists = nil
68
+ begin
69
+ os.download( figrc_url, repo_figrc_path )
70
+ repo_config_exists = true
71
+ rescue NotFoundError => e
72
+ repo_config_exists = false
73
+ end
74
+
75
+ return configuration if not repo_config_exists
76
+
77
+ begin
78
+ configuration.push_dataset(
79
+ JSON.parse(File.open(repo_figrc_path).read)
80
+ )
81
+ rescue JSON::ParserError => exception
82
+ translate_parse_error(exception, figrc_url)
83
+ end
84
+
85
+ return
86
+ end
87
+
88
+ def self.translate_parse_error(json_parse_error, config_file_path)
89
+ message = json_parse_error.message
90
+ message.chomp!
91
+
92
+ # JSON::ParserError tends to include final newline inside of single
93
+ # quotes, which makes error messages ugly.
94
+ message.sub!(/ \n+ ' \z /xm, %q<'>)
95
+
96
+ # Also, there's a useless source code line number in the message.
97
+ message.sub!(/ \A \d+ : \s+ /xm, %q<>)
98
+
99
+ raise ConfigFileError.new(
100
+ "Parse issue with #{config_file_path}: #{message}",
101
+ config_file_path
102
+ )
103
+ end
104
+ end
105
+ end
@@ -107,7 +107,7 @@ grammar Fig
107
107
  end
108
108
 
109
109
  rule descriptor
110
- ((package:package_name ("/" version:version_name)? (":" config:config_name)? ws) /
110
+ ((package:package_name ("/" version:version_name)? (":" config:config_name)? ws) /
111
111
  (":" config:config_name ws)) {
112
112
  def get_version
113
113
  elements.each do |element|
@@ -0,0 +1,14 @@
1
+ require 'fig/userinputerror'
2
+
3
+ module Fig
4
+ class Log4rConfigError < UserInputError
5
+ def initialize(config_file, original_exception)
6
+ super(
7
+ %Q<Problem with #{config_file}: #{original_exception.message}>
8
+ )
9
+
10
+ @config_file = config_file
11
+ @original_exception = original_exception
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,131 @@
1
+ require 'log4r'
2
+ require 'log4r/configurator'
3
+ require 'log4r/yamlconfigurator'
4
+
5
+ require 'fig/configfileerror'
6
+ require 'fig/log4rconfigerror'
7
+
8
+ module Fig; end
9
+
10
+ module Fig::Logging
11
+ if not Log4r::Logger['initial']
12
+ @@logger = Log4r::Logger.new('initial')
13
+ end
14
+
15
+ STRING_TO_LEVEL_MAPPING = {
16
+ 'off' => Log4r::OFF,
17
+ 'fatal' => Log4r::FATAL,
18
+ 'error' => Log4r::ERROR,
19
+ 'warn' => Log4r::WARN,
20
+ 'info' => Log4r::INFO,
21
+ 'debug' => Log4r::DEBUG,
22
+ 'all' => Log4r::ALL
23
+ }
24
+
25
+ def self.initialize_pre_configuration(log_level = nil)
26
+ log_level ||= 'info'
27
+
28
+ assign_log_level(@@logger, log_level)
29
+ setup_default_outputter(@@logger)
30
+ end
31
+
32
+ def self.initialize_post_configuration(
33
+ config_file = nil,
34
+ log_level = nil,
35
+ suppress_default_configuration = false
36
+ )
37
+ if config_file
38
+ begin
39
+ case config_file
40
+ when / [.] xml \z /x
41
+ Log4r::Configurator.load_xml_file(config_file)
42
+ when / [.] ya?ml \z /x
43
+ Log4r::YamlConfigurator.load_yaml_file(config_file)
44
+ else
45
+ raise ConfigFileError, %Q<Don't know what format #{config_file} is in.>, config_file
46
+ end
47
+
48
+ if Log4r::Logger['fig'].nil?
49
+ $stderr.puts %q<A value was provided for --log-config but no "fig" logger was defined.>
50
+ end
51
+ rescue Log4r::ConfigError, ArgumentError => exception
52
+ raise Log4rConfigError.new(config_file, exception)
53
+ end
54
+ end
55
+
56
+ if Log4r::Logger['fig'].nil?
57
+ @@logger = Log4r::Logger.new('fig')
58
+ else
59
+ @@logger = Log4r::Logger['fig']
60
+ end
61
+
62
+ if not config_file and not suppress_default_configuration
63
+ assign_log_level(@@logger, 'info')
64
+ setup_default_outputter(@@logger)
65
+ end
66
+
67
+ assign_log_level(@@logger, log_level)
68
+
69
+ return
70
+ end
71
+
72
+ def self.fatal(data = nil, propagated = nil)
73
+ @@logger.fatal data, propagated
74
+ end
75
+
76
+ def self.fatal?()
77
+ return @@logger.fatal?
78
+ end
79
+
80
+ def self.error(data = nil, propagated = nil)
81
+ @@logger.error data, propagated
82
+ end
83
+
84
+ def self.error?()
85
+ return @@logger.error?
86
+ end
87
+
88
+ def self.warn(data = nil, propagated = nil)
89
+ @@logger.warn data, propagated
90
+ end
91
+
92
+ def self.warn?()
93
+ return @@logger.warn?
94
+ end
95
+
96
+ def self.info(data = nil, propagated = nil)
97
+ @@logger.info data, propagated
98
+ end
99
+
100
+ def self.info?()
101
+ return @@logger.info?
102
+ end
103
+
104
+ def self.debug(data = nil, propagated = nil)
105
+ @@logger.debug data, propagated
106
+ end
107
+
108
+ def self.debug?()
109
+ return @@logger.debug?
110
+ end
111
+
112
+ private
113
+
114
+ def self.assign_log_level(logger, string_level)
115
+ return if string_level.nil?
116
+
117
+ level = STRING_TO_LEVEL_MAPPING[string_level.downcase]
118
+ logger.level = level
119
+ logger.outputters.each { | outputter | outputter.level = level }
120
+
121
+ return
122
+ end
123
+
124
+ def self.setup_default_outputter(logger)
125
+ outputter = Log4r::Outputter.stdout
126
+ logger.add outputter
127
+ outputter.formatter = Log4r::PatternFormatter.new :pattern => '%M'
128
+
129
+ return
130
+ end
131
+ end
@@ -0,0 +1,7 @@
1
+ require 'fig/userinputerror'
2
+
3
+ module Fig
4
+ # A problem with file transfer over the network.
5
+ class NetworkError < UserInputError
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ module Fig
2
+ class NotFoundError < StandardError
3
+ end
4
+ end