fig18 0.1.39 → 0.1.40

Sign up to get free protection for your applications and to get access to all the features.
@@ -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