fig18 0.1.41 → 0.1.42
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/Changes +10 -0
- data/VERSION +1 -1
- data/lib/fig/environment.rb +8 -4
- data/lib/fig/grammar.treetop +57 -17
- data/lib/fig/options.rb +10 -5
- data/lib/fig/os.rb +33 -12
- data/lib/fig/package/archive.rb +24 -0
- data/lib/fig/package/command.rb +20 -0
- data/lib/fig/package/configuration.rb +40 -0
- data/lib/fig/package/include.rb +30 -0
- data/lib/fig/package/install.rb +21 -0
- data/lib/fig/package/override.rb +21 -0
- data/lib/fig/package/path.rb +21 -0
- data/lib/fig/package/publish.rb +21 -0
- data/lib/fig/package/resource.rb +24 -0
- data/lib/fig/package/retrieve.rb +21 -0
- data/lib/fig/package/set.rb +21 -0
- data/lib/fig/package/statement.rb +12 -0
- data/lib/fig/package.rb +43 -190
- data/lib/fig/parser.rb +17 -4
- data/lib/fig/repository.rb +18 -23
- data/lib/fig/urlaccesserror.rb +6 -2
- data/lib/fig.rb +15 -7
- metadata +18 -125
data/lib/fig/package.rb
CHANGED
@@ -1,216 +1,69 @@
|
|
1
1
|
require 'fig/logging'
|
2
2
|
require 'fig/packageerror'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
Fig::Logging.fatal "Configuration not found: #{@package_name}/#{@version_name}:#{config_name}"
|
22
|
-
raise PackageError.new
|
23
|
-
end
|
24
|
-
|
25
|
-
def configs
|
26
|
-
@statements.select { |statement| statement.is_a?(Configuration) }
|
27
|
-
end
|
28
|
-
|
29
|
-
def retrieves
|
30
|
-
retrieves = {}
|
31
|
-
statements.each { |statement| retrieves[statement.var] = statement.path if statement.is_a?(Retrieve) }
|
32
|
-
retrieves
|
33
|
-
end
|
34
|
-
|
35
|
-
def archive_urls
|
36
|
-
@statements.select{|s| s.is_a?(Archive)}.map{|s|s.url}
|
37
|
-
end
|
38
|
-
|
39
|
-
def resource_urls
|
40
|
-
@statements.select{|s| s.is_a?(Resource)}.map{|s|s.url}
|
41
|
-
end
|
42
|
-
|
43
|
-
def unparse
|
44
|
-
@statements.map { |statement| statement.unparse('') }.join("\n")
|
45
|
-
end
|
46
|
-
|
47
|
-
def ==(other)
|
48
|
-
@package_name == other.package_name && @version_name == other.version_name && @statements.to_yaml == other.statements.to_yaml
|
49
|
-
end
|
50
|
-
|
51
|
-
def to_s
|
52
|
-
@package_name + '/' + @version_name
|
53
|
-
end
|
3
|
+
require 'fig/package/archive'
|
4
|
+
require 'fig/package/configuration'
|
5
|
+
require 'fig/package/resource'
|
6
|
+
require 'fig/package/retrieve'
|
7
|
+
|
8
|
+
module Fig; end
|
9
|
+
|
10
|
+
class Fig::Package
|
11
|
+
attr_reader :package_name, :version_name, :directory, :statements
|
12
|
+
attr_accessor :backtrace
|
13
|
+
|
14
|
+
def initialize(package_name, version_name, directory, statements)
|
15
|
+
@package_name = package_name
|
16
|
+
@version_name = version_name
|
17
|
+
@directory = directory
|
18
|
+
@statements = statements
|
19
|
+
@backtrace = nil
|
54
20
|
end
|
55
21
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
def initialize(url)
|
60
|
-
@url = url
|
61
|
-
end
|
62
|
-
|
63
|
-
def unparse(indent)
|
64
|
-
%Q<#{indent}archive "#{url}">
|
22
|
+
def [](config_name)
|
23
|
+
@statements.each do |stmt|
|
24
|
+
return stmt if stmt.is_a?(Configuration) && stmt.name == config_name
|
65
25
|
end
|
26
|
+
Fig::Logging.fatal "Configuration not found: #{@package_name}/#{@version_name}:#{config_name}"
|
27
|
+
raise PackageError.new
|
66
28
|
end
|
67
29
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
def initialize(url)
|
72
|
-
@url = url
|
73
|
-
end
|
74
|
-
|
75
|
-
def unparse(indent)
|
76
|
-
"#{indent}resource #{url}"
|
77
|
-
end
|
30
|
+
def configs
|
31
|
+
@statements.select { |statement| statement.is_a?(Configuration) }
|
78
32
|
end
|
79
33
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
@var = var
|
85
|
-
@path = path
|
86
|
-
end
|
87
|
-
|
88
|
-
def unparse(indent)
|
89
|
-
"#{indent}retrieve #{var}->#{path}"
|
90
|
-
end
|
34
|
+
def retrieves
|
35
|
+
retrieves = {}
|
36
|
+
statements.each { |statement| retrieves[statement.var] = statement.path if statement.is_a?(Retrieve) }
|
37
|
+
retrieves
|
91
38
|
end
|
92
39
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
def initialize(local_name, remote_name)
|
97
|
-
@local_name = local_name
|
98
|
-
@remote_name = remote_name
|
99
|
-
end
|
100
|
-
|
101
|
-
def unparse(indent)
|
102
|
-
"#{indent}publish #{@local_name}->#{@remote_name}"
|
103
|
-
end
|
40
|
+
def archive_urls
|
41
|
+
@statements.select{|s| s.is_a?(Archive)}.map{|s|s.url}
|
104
42
|
end
|
105
43
|
|
106
|
-
|
107
|
-
|
108
|
-
@statements = statements
|
109
|
-
end
|
110
|
-
|
111
|
-
def unparse(indent)
|
112
|
-
prefix = "\n#{indent}install"
|
113
|
-
body = @statements.map { |statement| statement.unparse(indent+' ') }.join("\n")
|
114
|
-
suffix = "#{indent}end"
|
115
|
-
return [prefix, body, suffix].join("\n")
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
class Configuration
|
120
|
-
attr_reader :name, :statements
|
121
|
-
|
122
|
-
def initialize(name, statements)
|
123
|
-
@name = name
|
124
|
-
@statements = statements
|
125
|
-
end
|
126
|
-
|
127
|
-
def with_name(name)
|
128
|
-
Configuration.new(name, statements)
|
129
|
-
end
|
130
|
-
|
131
|
-
def commands
|
132
|
-
result = statements.select { |statement| statement.is_a?(Command) }
|
133
|
-
result
|
134
|
-
end
|
135
|
-
|
136
|
-
def unparse(indent)
|
137
|
-
unparse_statements(indent, "config #{@name}", @statements, 'end')
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
class Path
|
142
|
-
attr_reader :name, :value
|
143
|
-
|
144
|
-
def initialize(name, value)
|
145
|
-
@name = name
|
146
|
-
@value = value
|
147
|
-
end
|
148
|
-
|
149
|
-
def unparse(indent)
|
150
|
-
"#{indent}append #{name}=#{value}"
|
151
|
-
end
|
44
|
+
def resource_urls
|
45
|
+
@statements.select{|s| s.is_a?(Resource)}.map{|s|s.url}
|
152
46
|
end
|
153
47
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
@name = name
|
159
|
-
@value = value
|
160
|
-
end
|
161
|
-
|
162
|
-
def unparse(indent)
|
163
|
-
"#{indent}set #{name}=#{value}"
|
48
|
+
def walk_statements(&block)
|
49
|
+
@statements.each do |statement|
|
50
|
+
yield statement
|
51
|
+
statement.walk_statements &block
|
164
52
|
end
|
165
53
|
end
|
166
54
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
def initialize(package_name, config_name, version_name, overrides)
|
171
|
-
@package_name = package_name
|
172
|
-
@config_name = config_name
|
173
|
-
@version_name = version_name
|
174
|
-
@overrides = overrides
|
175
|
-
end
|
176
|
-
|
177
|
-
def unparse(indent)
|
178
|
-
descriptor = ''
|
179
|
-
descriptor += @package_name if @package_name
|
180
|
-
descriptor += "/#{@version_name}" if @version_name
|
181
|
-
descriptor += ":#{@config_name}" if @config_name
|
182
|
-
@overrides.each do |override|
|
183
|
-
descriptor += override.unparse
|
184
|
-
end
|
185
|
-
return "#{indent}include #{descriptor}"
|
186
|
-
end
|
55
|
+
def unparse
|
56
|
+
@statements.map { |statement| statement.unparse('') }.join("\n")
|
187
57
|
end
|
188
58
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
def initialize(package_name, version_name)
|
193
|
-
@package_name = package_name
|
194
|
-
@version_name = version_name
|
195
|
-
end
|
196
|
-
|
197
|
-
def unparse()
|
198
|
-
return ' override ' + @package_name + '/' + @version_name
|
199
|
-
end
|
59
|
+
def ==(other)
|
60
|
+
return false if other.nil?
|
61
|
+
@package_name == other.package_name && @version_name == other.version_name && @statements.to_yaml == other.statements.to_yaml
|
200
62
|
end
|
201
63
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
def initialize(command)
|
206
|
-
@command = command
|
207
|
-
end
|
208
|
-
|
209
|
-
def unparse(indent)
|
210
|
-
%Q<#{indent}command "#{@command}">
|
211
|
-
end
|
64
|
+
def to_s
|
65
|
+
@package_name + '/' + @version_name
|
212
66
|
end
|
213
|
-
|
214
67
|
end
|
215
68
|
|
216
69
|
def unparse_statements(indent, prefix, statements, suffix)
|
data/lib/fig/parser.rb
CHANGED
@@ -4,21 +4,34 @@ require 'treetop'
|
|
4
4
|
require 'fig/grammar'
|
5
5
|
require 'fig/logging'
|
6
6
|
require 'fig/packageerror'
|
7
|
+
require 'fig/repository'
|
8
|
+
require 'fig/urlaccesserror'
|
7
9
|
|
8
10
|
module Fig
|
9
11
|
class Parser
|
10
|
-
def initialize
|
12
|
+
def initialize(application_config)
|
11
13
|
@parser = FigParser.new
|
14
|
+
@application_config = application_config
|
12
15
|
end
|
13
16
|
|
14
17
|
def parse_package(package_name, version_name, directory, input)
|
15
18
|
input = input.gsub(/#.*$/, '')
|
16
19
|
result = @parser.parse(" #{input} ")
|
17
20
|
if result.nil?
|
18
|
-
|
19
|
-
raise PackageError.new
|
21
|
+
Logging.fatal "#{directory}: #{@parser.failure_reason}"
|
22
|
+
raise PackageError.new("#{directory}: #{@parser.failure_reason}")
|
20
23
|
end
|
21
|
-
result.to_package(package_name, version_name, directory)
|
24
|
+
package = result.to_package(package_name, version_name, directory)
|
25
|
+
bad_urls = []
|
26
|
+
package.walk_statements do |statement|
|
27
|
+
statement.urls.each do |url|
|
28
|
+
# collect all bad urls in bad_urls
|
29
|
+
next if not Repository.is_url?(url)
|
30
|
+
bad_urls << url if not @application_config.url_access_allowed?(url)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
raise URLAccessError.new(bad_urls, package_name, version_name) if not bad_urls.empty?
|
34
|
+
return package
|
22
35
|
end
|
23
36
|
end
|
24
37
|
end
|
data/lib/fig/repository.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
require 'fig/logging'
|
2
2
|
require 'fig/notfounderror'
|
3
|
+
require 'fig/package/archive'
|
4
|
+
require 'fig/package/resource'
|
3
5
|
require 'fig/parser'
|
4
6
|
require 'fig/repositoryerror'
|
5
7
|
require 'fig/urlaccesserror'
|
6
8
|
|
7
9
|
module Fig
|
8
10
|
class Repository
|
11
|
+
def self.is_url?(url)
|
12
|
+
not (/ftp:\/\/|http:\/\/|file:\/\/|ssh:\/\// =~ url).nil?
|
13
|
+
end
|
14
|
+
|
9
15
|
def initialize(os, local_repository_dir, remote_repository_url, application_config, remote_repository_user=nil, update=false, update_if_missing=true)
|
10
16
|
@os = os
|
11
17
|
@local_repository_dir = local_repository_dir
|
@@ -14,7 +20,7 @@ module Fig
|
|
14
20
|
@application_config = application_config
|
15
21
|
@update = update
|
16
22
|
@update_if_missing = update_if_missing
|
17
|
-
@parser = Parser.new
|
23
|
+
@parser = Parser.new(@application_config)
|
18
24
|
|
19
25
|
@overrides = {}
|
20
26
|
if File.exist?('fig.properties')
|
@@ -54,17 +60,17 @@ module Fig
|
|
54
60
|
@os.clear_directory(local_dir)
|
55
61
|
fig_file = File.join(temp_dir, '.fig')
|
56
62
|
content = bundle_resources(package_statements).map do |statement|
|
57
|
-
if statement.is_a?(Publish)
|
63
|
+
if statement.is_a?(Package::Publish)
|
58
64
|
nil
|
59
|
-
elsif statement.is_a?(Archive) || statement.is_a?(Resource)
|
60
|
-
if statement.is_a?(Resource) && !is_url?(statement.url)
|
65
|
+
elsif statement.is_a?(Package::Archive) || statement.is_a?(Package::Resource)
|
66
|
+
if statement.is_a?(Package::Resource) && !Repository.is_url?(statement.url)
|
61
67
|
archive_name = statement.url
|
62
68
|
archive_remote = "#{remote_dir_for_package(package_name, version_name)}/#{statement.url}"
|
63
69
|
else
|
64
70
|
archive_name = statement.url.split('/').last
|
65
71
|
archive_remote = "#{remote_dir_for_package(package_name, version_name)}/#{archive_name}"
|
66
72
|
end
|
67
|
-
if
|
73
|
+
if Repository.is_url?(statement.url)
|
68
74
|
archive_local = File.join(temp_dir, archive_name)
|
69
75
|
@os.download(statement.url, archive_local)
|
70
76
|
else
|
@@ -72,7 +78,7 @@ module Fig
|
|
72
78
|
end
|
73
79
|
@os.upload(archive_local, archive_remote, @remote_repository_user) unless local_only
|
74
80
|
@os.copy(archive_local, local_dir + '/' + archive_name)
|
75
|
-
if statement.is_a?(Archive)
|
81
|
+
if statement.is_a?(Package::Archive)
|
76
82
|
@os.unpack_archive(local_dir, archive_name)
|
77
83
|
end
|
78
84
|
statement.class.new(archive_name).unparse('')
|
@@ -88,7 +94,7 @@ module Fig
|
|
88
94
|
def bundle_resources(package_statements)
|
89
95
|
resources = []
|
90
96
|
new_package_statements = package_statements.reject do |statement|
|
91
|
-
if statement.is_a?(Resource) && !is_url?(statement.url)
|
97
|
+
if statement.is_a?(Package::Resource) && !Repository.is_url?(statement.url)
|
92
98
|
resources << statement.url
|
93
99
|
true
|
94
100
|
else
|
@@ -99,7 +105,7 @@ module Fig
|
|
99
105
|
resources = expand_globs_from(resources)
|
100
106
|
file = 'resources.tar.gz'
|
101
107
|
@os.create_archive(file, resources)
|
102
|
-
new_package_statements.unshift(Archive.new(file))
|
108
|
+
new_package_statements.unshift(Package::Archive.new(file))
|
103
109
|
at_exit { File.delete(file) }
|
104
110
|
end
|
105
111
|
new_package_statements
|
@@ -139,7 +145,7 @@ module Fig
|
|
139
145
|
def read_remote_package(package_name, version_name)
|
140
146
|
url = remote_fig_file_for_package(package_name, version_name)
|
141
147
|
content = @os.read_url(url)
|
142
|
-
@parser.parse_package(package_name, version_name, nil, content)
|
148
|
+
return @parser.parse_package(package_name, version_name, nil, content)
|
143
149
|
end
|
144
150
|
|
145
151
|
def read_package_from_directory(dir, package_name, version_name)
|
@@ -159,9 +165,8 @@ module Fig
|
|
159
165
|
Logging.fatal "Package not found: #{package_name}/#{version_name}"
|
160
166
|
raise RepositoryError.new
|
161
167
|
end
|
162
|
-
modified_time = @os.mtime(file_name)
|
163
168
|
content = @os.read(file_name)
|
164
|
-
@parser.parse_package(package_name, version_name, File.dirname(file_name), content)
|
169
|
+
return @parser.parse_package(package_name, version_name, File.dirname(file_name), content)
|
165
170
|
end
|
166
171
|
|
167
172
|
def local_dir_for_package(package_name, version_name)
|
@@ -183,13 +188,13 @@ module Fig
|
|
183
188
|
temp_dir = temp_dir_for_package(package_name, version_name)
|
184
189
|
@os.clear_directory(temp_dir)
|
185
190
|
package.archive_urls.each do |archive_url|
|
186
|
-
if not is_url?(archive_url)
|
191
|
+
if not Repository.is_url?(archive_url)
|
187
192
|
archive_url = remote_dir_for_package(package_name, version_name) + '/' + archive_url
|
188
193
|
end
|
189
194
|
@os.download_archive(archive_url, File.join(temp_dir))
|
190
195
|
end
|
191
196
|
package.resource_urls.each do |resource_url|
|
192
|
-
if not is_url?(resource_url)
|
197
|
+
if not Repository.is_url?(resource_url)
|
193
198
|
resource_url = remote_dir_for_package(package_name, version_name) + '/' + resource_url
|
194
199
|
end
|
195
200
|
@os.download_resource(resource_url, File.join(temp_dir))
|
@@ -215,16 +220,6 @@ module Fig
|
|
215
220
|
expanded_files
|
216
221
|
end
|
217
222
|
|
218
|
-
def is_url?(url)
|
219
|
-
not (/ftp:\/\/|http:\/\/|file:\/\/|ssh:\/\// =~ url).nil?
|
220
|
-
end
|
221
|
-
|
222
|
-
def is_url_with_access?(url)
|
223
|
-
return false if not is_url?(url)
|
224
|
-
raise URLAccessError.new(url) if not @application_config.url_access_allowed?(url)
|
225
|
-
return true
|
226
|
-
end
|
227
|
-
|
228
223
|
def delete_local_package(package_name, version_name)
|
229
224
|
FileUtils.rm_rf(local_dir_for_package(package_name, version_name))
|
230
225
|
end
|
data/lib/fig/urlaccesserror.rb
CHANGED
@@ -2,8 +2,12 @@ require 'fig/userinputerror'
|
|
2
2
|
|
3
3
|
module Fig
|
4
4
|
class URLAccessError < UserInputError
|
5
|
-
|
6
|
-
|
5
|
+
attr_reader :urls, :package, :version
|
6
|
+
|
7
|
+
def initialize(urls, package, version)
|
8
|
+
@urls = urls
|
9
|
+
@package = package
|
10
|
+
@version = version
|
7
11
|
end
|
8
12
|
end
|
9
13
|
end
|
data/lib/fig.rb
CHANGED
@@ -7,6 +7,9 @@ require 'fig/figrc'
|
|
7
7
|
require 'fig/logging'
|
8
8
|
require 'fig/options'
|
9
9
|
require 'fig/os'
|
10
|
+
require 'fig/package'
|
11
|
+
require 'fig/package/configuration'
|
12
|
+
require 'fig/package/publish'
|
10
13
|
require 'fig/parser'
|
11
14
|
require 'fig/repository'
|
12
15
|
require 'fig/retriever'
|
@@ -18,9 +21,9 @@ module Fig
|
|
18
21
|
|
19
22
|
def parse_descriptor(descriptor)
|
20
23
|
# todo should use treetop for these:
|
21
|
-
package_name = descriptor =~
|
22
|
-
config_name
|
23
|
-
version_name = descriptor =~
|
24
|
+
package_name = descriptor =~ %r< ^ ( [^:/]+ ) >x ? $1 : nil
|
25
|
+
config_name = descriptor =~ %r< : ( [^:/]+ ) >x ? $1 : nil
|
26
|
+
version_name = descriptor =~ %r< / ( [^:/]+ ) >x ? $1 : nil
|
24
27
|
return package_name, config_name, version_name
|
25
28
|
end
|
26
29
|
|
@@ -129,7 +132,7 @@ module Fig
|
|
129
132
|
end
|
130
133
|
|
131
134
|
if input
|
132
|
-
package = Parser.new.parse_package(nil, nil, '.', input)
|
135
|
+
package = Parser.new(configuration).parse_package(nil, nil, '.', input)
|
133
136
|
direct_retrieves=[]
|
134
137
|
if options[:retrieve]
|
135
138
|
package.retrieves.each do |var, path|
|
@@ -162,8 +165,8 @@ module Fig
|
|
162
165
|
return 10
|
163
166
|
end
|
164
167
|
if not options[:modifiers].empty?
|
165
|
-
publish_statements = options[:resources] + options[:archives] + [Configuration.new('default', options[:modifiers])]
|
166
|
-
publish_statements << Publish.new('default','default')
|
168
|
+
publish_statements = options[:resources] + options[:archives] + [Package::Configuration.new('default', options[:modifiers])]
|
169
|
+
publish_statements << Package::Publish.new('default','default')
|
167
170
|
elsif not package.statements.empty?
|
168
171
|
publish_statements = package.statements
|
169
172
|
else
|
@@ -208,7 +211,8 @@ module Fig
|
|
208
211
|
return_code = run_fig(argv)
|
209
212
|
return return_code
|
210
213
|
rescue URLAccessError => exception
|
211
|
-
|
214
|
+
urls = exception.urls.join(', ')
|
215
|
+
$stderr.puts "Access to #{urls} in #{exception.package}/#{exception.version} not allowed."
|
212
216
|
return 1
|
213
217
|
rescue UserInputError => exception
|
214
218
|
# If there's no message, we assume that the cause has already been logged.
|
@@ -216,6 +220,10 @@ module Fig
|
|
216
220
|
$stderr.puts exception.to_s
|
217
221
|
end
|
218
222
|
|
223
|
+
return 1
|
224
|
+
rescue OptionParser::InvalidOption => exception
|
225
|
+
$stderr.puts exception.to_s
|
226
|
+
$stderr.puts USAGE
|
219
227
|
return 1
|
220
228
|
end
|
221
229
|
end
|