fig 0.1.69 → 0.1.71
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 +45 -0
- data/LICENSE +27 -0
- data/README.md +45 -0
- data/lib/fig.rb +1 -1
- data/lib/fig/application_configuration.rb +10 -10
- data/lib/fig/command.rb +48 -12
- data/lib/fig/command/action.rb +4 -0
- data/lib/fig/command/action/dump_package_definition_parsed.rb +43 -0
- data/lib/fig/command/action/dump_package_definition_text.rb +44 -0
- data/lib/fig/command/action/help.rb +1 -1
- data/lib/fig/command/action/help_long.rb +29 -0
- data/lib/fig/command/action/options.rb +30 -0
- data/lib/fig/command/action/role/publish.rb +4 -0
- data/lib/fig/command/options.rb +70 -45
- data/lib/fig/command/options/parser.rb +88 -30
- data/lib/fig/figrc.rb +20 -3
- data/lib/fig/grammar.treetop +17 -85
- data/lib/fig/package_descriptor.rb +12 -0
- data/lib/fig/parser.rb +29 -0
- data/lib/fig/parser_package_build_state.rb +110 -2
- data/lib/fig/runtime_environment.rb +8 -5
- data/lib/fig/statement/asset.rb +19 -0
- data/lib/fig/statement/configuration.rb +4 -1
- data/lib/fig/statement/path.rb +1 -1
- data/lib/fig/statement/set.rb +2 -2
- data/lib/fig/update_lock.rb +29 -8
- metadata +32 -26
data/lib/fig/grammar.treetop
CHANGED
|
@@ -1,32 +1,11 @@
|
|
|
1
1
|
# Treetop (http://treetop.rubyforge.org/) grammar for package definitions.
|
|
2
2
|
|
|
3
|
-
require 'fig/package'
|
|
4
|
-
require 'fig/package_descriptor'
|
|
5
|
-
require 'fig/parser'
|
|
6
|
-
require 'fig/statement/archive'
|
|
7
|
-
require 'fig/statement/command'
|
|
8
|
-
require 'fig/statement/configuration'
|
|
9
|
-
require 'fig/statement/include'
|
|
10
|
-
require 'fig/statement/override'
|
|
11
|
-
require 'fig/statement/path'
|
|
12
|
-
require 'fig/statement/resource'
|
|
13
|
-
require 'fig/statement/retrieve'
|
|
14
|
-
require 'fig/statement/set'
|
|
15
|
-
|
|
16
3
|
module Fig
|
|
17
4
|
grammar Fig
|
|
18
5
|
rule package
|
|
19
6
|
optional_ws statements:(package_statement*) optional_ws {
|
|
20
7
|
def to_package(directory, build_state)
|
|
21
|
-
|
|
22
|
-
build_state.descriptor.name,
|
|
23
|
-
build_state.descriptor.version,
|
|
24
|
-
directory,
|
|
25
|
-
statements.elements.map do
|
|
26
|
-
|statement|
|
|
27
|
-
statement.to_package_statement(build_state)
|
|
28
|
-
end
|
|
29
|
-
)
|
|
8
|
+
return build_state.new_package_statement(directory, statements)
|
|
30
9
|
end
|
|
31
10
|
}
|
|
32
11
|
end
|
|
@@ -35,13 +14,13 @@ module Fig
|
|
|
35
14
|
archive / resource / retrieve / config
|
|
36
15
|
end
|
|
37
16
|
|
|
17
|
+
# Note that these are being parsed like they allow globbing despite
|
|
18
|
+
# globbing not being performed.
|
|
38
19
|
rule archive
|
|
39
20
|
statement_start:"archive" ws resource_url {
|
|
40
21
|
def to_package_statement(build_state)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
build_state.source_description,
|
|
44
|
-
resource_url.value.text_value
|
|
22
|
+
return build_state.new_asset_statement(
|
|
23
|
+
Statement::Archive, statement_start, resource_url
|
|
45
24
|
)
|
|
46
25
|
end
|
|
47
26
|
}
|
|
@@ -50,10 +29,8 @@ module Fig
|
|
|
50
29
|
rule resource
|
|
51
30
|
statement_start:"resource" ws resource_url {
|
|
52
31
|
def to_package_statement(build_state)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
build_state.source_description,
|
|
56
|
-
resource_url.value.text_value
|
|
32
|
+
return build_state.new_asset_statement(
|
|
33
|
+
Statement::Resource, statement_start, resource_url
|
|
57
34
|
)
|
|
58
35
|
end
|
|
59
36
|
}
|
|
@@ -62,12 +39,7 @@ module Fig
|
|
|
62
39
|
rule retrieve
|
|
63
40
|
statement_start:"retrieve" ws var:environment_variable_name "->" path:retrieve_path ws {
|
|
64
41
|
def to_package_statement(build_state)
|
|
65
|
-
|
|
66
|
-
build_state.node_location(statement_start),
|
|
67
|
-
build_state.source_description,
|
|
68
|
-
var.text_value,
|
|
69
|
-
path.text_value
|
|
70
|
-
)
|
|
42
|
+
return build_state.new_retrieve_statement(statement_start, var, path)
|
|
71
43
|
end
|
|
72
44
|
}
|
|
73
45
|
end
|
|
@@ -79,14 +51,8 @@ module Fig
|
|
|
79
51
|
rule config
|
|
80
52
|
statement_start:"config" ws config_name ws statements:config_statement* "end" ws {
|
|
81
53
|
def to_package_statement(build_state)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
build_state.source_description,
|
|
85
|
-
config_name.text_value,
|
|
86
|
-
statements.elements.map do
|
|
87
|
-
|statement|
|
|
88
|
-
statement.to_config_statement(build_state)
|
|
89
|
-
end
|
|
54
|
+
return build_state.new_configuration_statement(
|
|
55
|
+
statement_start, config_name, statements
|
|
90
56
|
)
|
|
91
57
|
end
|
|
92
58
|
}
|
|
@@ -103,19 +69,8 @@ module Fig
|
|
|
103
69
|
rule include
|
|
104
70
|
statement_start:"include" ws descriptor_string ws {
|
|
105
71
|
def to_config_statement(build_state)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
descriptor_string.text_value.strip,
|
|
109
|
-
:source_description =>
|
|
110
|
-
build_state.node_location_description(descriptor_string),
|
|
111
|
-
:validation_context => ' for an include statement'
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
Statement::Include.new(
|
|
115
|
-
build_state.node_location(statement_start),
|
|
116
|
-
build_state.source_description,
|
|
117
|
-
include_descriptor,
|
|
118
|
-
build_state.descriptor
|
|
72
|
+
return build_state.new_include_statement(
|
|
73
|
+
statement_start, descriptor_string
|
|
119
74
|
)
|
|
120
75
|
end
|
|
121
76
|
}
|
|
@@ -124,19 +79,8 @@ module Fig
|
|
|
124
79
|
rule override
|
|
125
80
|
statement_start:"override" ws descriptor_string ws {
|
|
126
81
|
def to_config_statement(build_state)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
descriptor_string.text_value.strip,
|
|
130
|
-
:source_description =>
|
|
131
|
-
build_state.node_location_description(descriptor_string),
|
|
132
|
-
:validation_context => ' for an override statement'
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
return Statement::Override.new(
|
|
136
|
-
build_state.node_location(statement_start),
|
|
137
|
-
build_state.source_description,
|
|
138
|
-
descriptor.name,
|
|
139
|
-
descriptor.version
|
|
82
|
+
return build_state.new_override_statement(
|
|
83
|
+
statement_start, descriptor_string
|
|
140
84
|
)
|
|
141
85
|
end
|
|
142
86
|
}
|
|
@@ -169,11 +113,7 @@ module Fig
|
|
|
169
113
|
rule command
|
|
170
114
|
statement_start:"command" ws string {
|
|
171
115
|
def to_config_statement(build_state)
|
|
172
|
-
|
|
173
|
-
build_state.node_location(statement_start),
|
|
174
|
-
build_state.source_description,
|
|
175
|
-
string.value.text_value
|
|
176
|
-
)
|
|
116
|
+
return build_state.new_command_statement(statement_start, string)
|
|
177
117
|
end
|
|
178
118
|
}
|
|
179
119
|
end
|
|
@@ -186,14 +126,6 @@ module Fig
|
|
|
186
126
|
[\S]+
|
|
187
127
|
end
|
|
188
128
|
|
|
189
|
-
rule package_name
|
|
190
|
-
[a-zA-Z0-9_.-]+
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
rule version_name
|
|
194
|
-
[a-zA-Z0-9_.-]+
|
|
195
|
-
end
|
|
196
|
-
|
|
197
129
|
rule resource_url
|
|
198
130
|
# Unquoted allows globbing for files, quoted does not.
|
|
199
131
|
#
|
|
@@ -201,14 +133,14 @@ module Fig
|
|
|
201
133
|
# @ - To allow for package substitution
|
|
202
134
|
# "<>| - Characters not allowed in filenames on Windows
|
|
203
135
|
# \s - Necessary for the "ws" token to work
|
|
204
|
-
(
|
|
136
|
+
(url:[^@"<>|\s]+ ws)
|
|
205
137
|
|
|
206
138
|
# Quoted, anything but:
|
|
207
139
|
# @ - To allow for package substitution
|
|
208
140
|
# "<>| - Characters not allowed in filenames on Windows
|
|
209
141
|
# *?\[\]{} - Characters significant to Dir.glob()
|
|
210
142
|
# \s - We just don't want these. :] (May need to allow space.)
|
|
211
|
-
/ ('"'
|
|
143
|
+
/ ('"' url:[^@"<>|*?\[\]{}\s]+ '"' ws)
|
|
212
144
|
end
|
|
213
145
|
|
|
214
146
|
rule ws
|
|
@@ -64,6 +64,7 @@ class Fig::PackageDescriptor
|
|
|
64
64
|
validate_component name, 'name', :name, options
|
|
65
65
|
validate_component version, 'version', :version, options
|
|
66
66
|
validate_component config, 'config', :config, options
|
|
67
|
+
validate_name options
|
|
67
68
|
validate_across_components options
|
|
68
69
|
end
|
|
69
70
|
|
|
@@ -112,6 +113,17 @@ class Fig::PackageDescriptor
|
|
|
112
113
|
)
|
|
113
114
|
end
|
|
114
115
|
|
|
116
|
+
def validate_name(options)
|
|
117
|
+
return if @name.nil?
|
|
118
|
+
|
|
119
|
+
return if ! Fig::Parser.strict_keyword? @name
|
|
120
|
+
|
|
121
|
+
raise Fig::PackageDescriptorParseError.new(
|
|
122
|
+
%Q<Invalid package name; "#{@name}" is a keyword#{standard_exception_suffix(options)}>,
|
|
123
|
+
@original_string
|
|
124
|
+
)
|
|
125
|
+
end
|
|
126
|
+
|
|
115
127
|
def throw_presence_exception(name, presence_requirement_symbol, options)
|
|
116
128
|
presence = options[presence_requirement_symbol]
|
|
117
129
|
raise Fig::PackageDescriptorParseError.new(
|
data/lib/fig/parser.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'set'
|
|
1
2
|
require 'treetop'
|
|
2
3
|
|
|
3
4
|
require 'fig/grammar' # this is grammar.treetop, not grammar.rb.
|
|
@@ -14,6 +15,19 @@ module Fig; end
|
|
|
14
15
|
# Parses .fig files (wrapping the Treetop-generated parser object) and deals
|
|
15
16
|
# with a few restrictions on them.
|
|
16
17
|
class Fig::Parser
|
|
18
|
+
# Keywords that we really want to lock down.
|
|
19
|
+
def self.strict_keyword?(string)
|
|
20
|
+
# "config" is considered too useful for users, so we allow that where we
|
|
21
|
+
# restrict other keywords.
|
|
22
|
+
return false if string == 'config'
|
|
23
|
+
|
|
24
|
+
return keyword? string
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.keyword?(string)
|
|
28
|
+
return KEYWORDS.include? string
|
|
29
|
+
end
|
|
30
|
+
|
|
17
31
|
def initialize(application_config, check_include_versions)
|
|
18
32
|
# Fig::FigParser class is synthesized by Treetop.
|
|
19
33
|
@treetop_parser = Fig::FigParser.new
|
|
@@ -51,6 +65,21 @@ class Fig::Parser
|
|
|
51
65
|
|
|
52
66
|
private
|
|
53
67
|
|
|
68
|
+
KEYWORDS = Set.new
|
|
69
|
+
KEYWORDS << 'add'
|
|
70
|
+
KEYWORDS << 'append'
|
|
71
|
+
KEYWORDS << 'archive'
|
|
72
|
+
KEYWORDS << 'command'
|
|
73
|
+
KEYWORDS << 'config'
|
|
74
|
+
KEYWORDS << 'end'
|
|
75
|
+
KEYWORDS << 'include'
|
|
76
|
+
KEYWORDS << 'override'
|
|
77
|
+
KEYWORDS << 'path'
|
|
78
|
+
KEYWORDS << 'resource'
|
|
79
|
+
KEYWORDS << 'retrieve'
|
|
80
|
+
KEYWORDS << 'set'
|
|
81
|
+
|
|
82
|
+
|
|
54
83
|
def extend_source_description(directory, original_description)
|
|
55
84
|
if original_description
|
|
56
85
|
extended = original_description
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
require 'fig/package'
|
|
1
2
|
require 'fig/package_parse_error'
|
|
2
3
|
require 'fig/statement'
|
|
4
|
+
require 'fig/statement/archive'
|
|
5
|
+
require 'fig/statement/command'
|
|
6
|
+
require 'fig/statement/configuration'
|
|
7
|
+
require 'fig/statement/include'
|
|
8
|
+
require 'fig/statement/override'
|
|
9
|
+
require 'fig/statement/path'
|
|
10
|
+
require 'fig/statement/resource'
|
|
11
|
+
require 'fig/statement/retrieve'
|
|
12
|
+
require 'fig/statement/set'
|
|
3
13
|
|
|
4
14
|
module Fig; end
|
|
5
15
|
|
|
@@ -33,6 +43,93 @@ class Fig::ParserPackageBuildState
|
|
|
33
43
|
)
|
|
34
44
|
end
|
|
35
45
|
|
|
46
|
+
def new_package_statement(directory, statements)
|
|
47
|
+
return Fig::Package.new(
|
|
48
|
+
descriptor.name,
|
|
49
|
+
descriptor.version,
|
|
50
|
+
directory,
|
|
51
|
+
statements.elements.map do
|
|
52
|
+
|statement|
|
|
53
|
+
statement.to_package_statement(self)
|
|
54
|
+
end
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def new_asset_statement(statement_class, keyword_node, url_node)
|
|
59
|
+
url = url_node.url.text_value
|
|
60
|
+
|
|
61
|
+
statement_class.validate_url(url) {
|
|
62
|
+
|error_description|
|
|
63
|
+
|
|
64
|
+
raise_invalid_value_parse_error(
|
|
65
|
+
keyword_node, url_node.url, 'URL/path', error_description
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return statement_class.new(
|
|
70
|
+
node_location(keyword_node), source_description, url
|
|
71
|
+
)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def new_retrieve_statement(keyword_node, variable_name_node, path_node)
|
|
75
|
+
return Fig::Statement::Retrieve.new(
|
|
76
|
+
node_location(keyword_node),
|
|
77
|
+
source_description,
|
|
78
|
+
variable_name_node.text_value,
|
|
79
|
+
path_node.text_value
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def new_configuration_statement(keyword_node, name_node, statements)
|
|
84
|
+
if Fig::Parser.strict_keyword? name_node.text_value
|
|
85
|
+
raise_invalid_value_parse_error(
|
|
86
|
+
keyword_node, name_node, 'name', 'is a keyword.'
|
|
87
|
+
)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
return Fig::Statement::Configuration.new(
|
|
91
|
+
node_location(keyword_node),
|
|
92
|
+
source_description,
|
|
93
|
+
name_node.text_value,
|
|
94
|
+
statements.elements.map do
|
|
95
|
+
|statement|
|
|
96
|
+
statement.to_config_statement(self)
|
|
97
|
+
end
|
|
98
|
+
)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def new_include_statement(keyword_node, descriptor_node)
|
|
102
|
+
include_descriptor =
|
|
103
|
+
Fig::Statement::Include.parse_descriptor(
|
|
104
|
+
descriptor_node.text_value.strip,
|
|
105
|
+
:source_description => node_location_description(descriptor_node),
|
|
106
|
+
:validation_context => ' for an include statement'
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
return Fig::Statement::Include.new(
|
|
110
|
+
node_location(keyword_node),
|
|
111
|
+
source_description,
|
|
112
|
+
include_descriptor,
|
|
113
|
+
descriptor
|
|
114
|
+
)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def new_override_statement(keyword_node, descriptor_node)
|
|
118
|
+
override_descriptor =
|
|
119
|
+
Fig::Statement::Override.parse_descriptor(
|
|
120
|
+
descriptor_node.text_value.strip,
|
|
121
|
+
:source_description => node_location_description(descriptor_node),
|
|
122
|
+
:validation_context => ' for an override statement'
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
return Fig::Statement::Override.new(
|
|
126
|
+
node_location(keyword_node),
|
|
127
|
+
source_description,
|
|
128
|
+
override_descriptor.name,
|
|
129
|
+
override_descriptor.version
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
|
|
36
133
|
def new_environment_variable_statement(
|
|
37
134
|
statement_class, keyword_node, value_node
|
|
38
135
|
)
|
|
@@ -40,6 +137,7 @@ class Fig::ParserPackageBuildState
|
|
|
40
137
|
raise_invalid_value_parse_error(
|
|
41
138
|
keyword_node,
|
|
42
139
|
value_node,
|
|
140
|
+
'value',
|
|
43
141
|
statement_class.const_get(:ARGUMENT_DESCRIPTION)
|
|
44
142
|
)
|
|
45
143
|
}
|
|
@@ -48,9 +146,19 @@ class Fig::ParserPackageBuildState
|
|
|
48
146
|
)
|
|
49
147
|
end
|
|
50
148
|
|
|
51
|
-
def
|
|
149
|
+
def new_command_statement(keyword_node, command_node)
|
|
150
|
+
return Fig::Statement::Command.new(
|
|
151
|
+
node_location(keyword_node),
|
|
152
|
+
source_description,
|
|
153
|
+
command_node.value.text_value
|
|
154
|
+
)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def raise_invalid_value_parse_error(
|
|
158
|
+
keyword_node, value_node, value_name, description
|
|
159
|
+
)
|
|
52
160
|
raise Fig::PackageParseError.new(
|
|
53
|
-
%Q<Invalid
|
|
161
|
+
%Q<Invalid #{value_name} for #{keyword_node.text_value} statement: "#{value_node.text_value}" #{description}#{node_location_description(value_node)}>
|
|
54
162
|
)
|
|
55
163
|
end
|
|
56
164
|
end
|
|
@@ -159,13 +159,12 @@ class Fig::RuntimeEnvironment
|
|
|
159
159
|
|
|
160
160
|
# Check to see if this include has been overridden.
|
|
161
161
|
if backtrace
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
)
|
|
162
|
+
override_package_name = descriptor.name || base_package.name
|
|
163
|
+
override = backtrace.get_override(override_package_name)
|
|
165
164
|
if override
|
|
166
165
|
resolved_descriptor =
|
|
167
166
|
Fig::PackageDescriptor.new(
|
|
168
|
-
|
|
167
|
+
override_package_name, override, descriptor.config
|
|
169
168
|
)
|
|
170
169
|
end
|
|
171
170
|
end
|
|
@@ -433,7 +432,11 @@ class Fig::RuntimeEnvironment
|
|
|
433
432
|
def raise_repository_error(message, backtrace, package)
|
|
434
433
|
string_handle = StringIO.new
|
|
435
434
|
backtrace.dump(string_handle) if backtrace
|
|
436
|
-
|
|
435
|
+
|
|
436
|
+
if package && package.backtrace && package.backtrace != backtrace
|
|
437
|
+
package.backtrace.dump(string_handle)
|
|
438
|
+
end
|
|
439
|
+
|
|
437
440
|
stacktrace = string_handle.string
|
|
438
441
|
|
|
439
442
|
raise Fig::RepositoryError.new(
|
data/lib/fig/statement/asset.rb
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
require 'fig/parser'
|
|
2
|
+
|
|
1
3
|
module Fig; end
|
|
2
4
|
class Fig::Statement; end
|
|
3
5
|
|
|
4
6
|
# Some sort of file to be included in a package.
|
|
5
7
|
module Fig::Statement::Asset
|
|
8
|
+
def self.included(class_included_into)
|
|
9
|
+
class_included_into.extend(ClassMethods)
|
|
10
|
+
|
|
11
|
+
return
|
|
12
|
+
end
|
|
13
|
+
|
|
6
14
|
def urls()
|
|
7
15
|
return [ url() ]
|
|
8
16
|
end
|
|
@@ -16,4 +24,15 @@ module Fig::Statement::Asset
|
|
|
16
24
|
# going to fix this now.
|
|
17
25
|
return url().split('/').last()
|
|
18
26
|
end
|
|
27
|
+
|
|
28
|
+
module ClassMethods
|
|
29
|
+
def validate_url(url)
|
|
30
|
+
# "config" is a reasonable asset name, so we let that pass.
|
|
31
|
+
if Fig::Parser.strict_keyword?(url)
|
|
32
|
+
yield 'is a keyword.'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
return
|
|
36
|
+
end
|
|
37
|
+
end
|
|
19
38
|
end
|