fig 0.1.77 → 0.1.79
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 +58 -1
- data/bin/fig +1 -1
- data/lib/fig.rb +1 -1
- data/lib/fig/command.rb +3 -3
- data/lib/fig/command/action/dump_package_definition_parsed.rb +5 -4
- data/lib/fig/command/action/list_variables/all_configs.rb +2 -5
- data/lib/fig/command/action/publish_local.rb +1 -1
- data/lib/fig/command/action/role/list_variables_in_a_tree.rb +2 -5
- data/lib/fig/command/action/run_command_line.rb +10 -3
- data/lib/fig/command/action/run_command_statement.rb +1 -1
- data/lib/fig/command/options.rb +8 -7
- data/lib/fig/command/options/parser.rb +1 -1
- data/lib/fig/environment_variables/case_insensitive.rb +1 -1
- data/lib/fig/environment_variables/case_sensitive.rb +1 -1
- data/lib/fig/figrc.rb +10 -10
- data/lib/fig/{not_found_error.rb → file_not_found_error.rb} +1 -1
- data/lib/fig/grammar/v0.rb +174 -173
- data/lib/fig/grammar/v0.treetop +27 -21
- data/lib/fig/grammar/v1.rb +477 -171
- data/lib/fig/grammar/v1.treetop +34 -22
- data/lib/fig/operating_system.rb +139 -60
- data/lib/fig/package.rb +8 -4
- data/lib/fig/package_definition_text_assembler.rb +31 -23
- data/lib/fig/parser.rb +3 -5
- data/lib/fig/parser_package_build_state.rb +15 -14
- data/lib/fig/repository.rb +41 -28
- data/lib/fig/repository_package_publisher.rb +20 -25
- data/lib/fig/runtime_environment.rb +136 -87
- data/lib/fig/statement.rb +15 -116
- data/lib/fig/statement/archive.rb +6 -4
- data/lib/fig/statement/asset.rb +50 -35
- data/lib/fig/statement/command.rb +6 -2
- data/lib/fig/statement/configuration.rb +10 -2
- data/lib/fig/statement/environment_variable.rb +35 -0
- data/lib/fig/statement/grammar_version.rb +6 -2
- data/lib/fig/statement/include.rb +6 -2
- data/lib/fig/statement/override.rb +6 -2
- data/lib/fig/statement/path.rb +7 -8
- data/lib/fig/statement/resource.rb +7 -3
- data/lib/fig/statement/retrieve.rb +10 -2
- data/lib/fig/statement/set.rb +7 -8
- data/lib/fig/string_tokenizer.rb +195 -0
- data/lib/fig/tokenized_string.rb +22 -0
- data/lib/fig/tokenized_string/plain_segment.rb +24 -0
- data/lib/fig/tokenized_string/token.rb +18 -0
- data/lib/fig/unparser.rb +84 -1
- data/lib/fig/unparser/v0.rb +4 -0
- data/lib/fig/unparser/v1.rb +7 -7
- data/lib/fig/url.rb +12 -1
- data/lib/fig/{url_access_error.rb → url_access_disallowed_error.rb} +2 -2
- metadata +129 -128
- data/lib/fig/grammar/v0_asset_location.rb +0 -162
- data/lib/fig/grammar/v0_ish.rb +0 -1356
- data/lib/fig/grammar/v1_asset_location.rb +0 -162
- data/lib/fig/grammar/v2.rb +0 -1478
data/lib/fig/statement.rb
CHANGED
@@ -26,121 +26,6 @@ class Fig::Statement
|
|
26
26
|
return description
|
27
27
|
end
|
28
28
|
|
29
|
-
# Parameter will be modified.
|
30
|
-
#
|
31
|
-
# Takes a block that is invoked when there is an error. Block receives a
|
32
|
-
# single parameter of an error message that is the end of a statement
|
33
|
-
# describing the problem, with no leading space character. For example,
|
34
|
-
# given «'foo», the block will receive a message like 'has unbalanced single
|
35
|
-
# quotes.'.
|
36
|
-
#
|
37
|
-
# Returns whether parameter was single-quoted; if there was a parse error,
|
38
|
-
# then the return value will be nil (and the block will have been invoked).
|
39
|
-
def self.strip_quotes_and_process_escapes!(string, &error_block)
|
40
|
-
return false if string.length == 0
|
41
|
-
|
42
|
-
replaced_quotes = strip_single_quotes!(string, &error_block)
|
43
|
-
return true if replaced_quotes
|
44
|
-
return if replaced_quotes.nil?
|
45
|
-
|
46
|
-
return process_escapes_and_strip_double_quotes!(string, &error_block)
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def self.strip_single_quotes!(string)
|
52
|
-
return false if string[0..0] != %q<'> && string[-1..-1] != %q<'>
|
53
|
-
|
54
|
-
if string.length == 1 || string[0..0] != %q<'> || string[-1..-1] != %q<'>
|
55
|
-
yield 'has unbalanced single quotes.'
|
56
|
-
return
|
57
|
-
end
|
58
|
-
|
59
|
-
if string =~ %r< \A ' [^']* ' .* ' \z >xs
|
60
|
-
yield %q<isn't permitted because it has a single quote inside single quotes.>
|
61
|
-
return
|
62
|
-
end
|
63
|
-
|
64
|
-
string.sub!(%r< \A ' (.*) ' \z >xs, '\1')
|
65
|
-
|
66
|
-
return true
|
67
|
-
end
|
68
|
-
|
69
|
-
ALLOWED_ESCAPED_CHARACTERS = Set.new
|
70
|
-
ALLOWED_ESCAPED_CHARACTERS << '\\'
|
71
|
-
ALLOWED_ESCAPED_CHARACTERS << %q<'>
|
72
|
-
ALLOWED_ESCAPED_CHARACTERS << %q<">
|
73
|
-
ALLOWED_ESCAPED_CHARACTERS << '@' # Environment variable package replacement
|
74
|
-
|
75
|
-
def self.process_escapes_and_strip_double_quotes!(string)
|
76
|
-
if string[0..0] == %q<"> && (string.length == 1 || string[-1..-1] != %q<">)
|
77
|
-
yield 'has unbalanced double quotes.'
|
78
|
-
return
|
79
|
-
end
|
80
|
-
|
81
|
-
new_string = ''
|
82
|
-
|
83
|
-
characters = string.each_char
|
84
|
-
initial_character = characters.next
|
85
|
-
last_character = nil
|
86
|
-
had_starting_quote = initial_character == %q<">
|
87
|
-
in_escape = initial_character == '\\'
|
88
|
-
if ! had_starting_quote && ! in_escape
|
89
|
-
new_string << initial_character
|
90
|
-
end
|
91
|
-
|
92
|
-
last_was_escaped = nil
|
93
|
-
loop do
|
94
|
-
last_character = character = characters.next
|
95
|
-
if in_escape
|
96
|
-
if ! ALLOWED_ESCAPED_CHARACTERS.include? character
|
97
|
-
yield "contains a bad escape sequence (\\#{character})."
|
98
|
-
return
|
99
|
-
end
|
100
|
-
|
101
|
-
new_string << character
|
102
|
-
in_escape = false
|
103
|
-
last_was_escaped = true
|
104
|
-
elsif character == %q<">
|
105
|
-
# If we're at the end of the string, we'll get bounced out of the loop
|
106
|
-
# by a StopIteration exception.
|
107
|
-
characters.next
|
108
|
-
yield 'has an unescaped double quote in the middle.'
|
109
|
-
return
|
110
|
-
elsif character == %q<'>
|
111
|
-
yield 'has an unescaped single quote in the middle.'
|
112
|
-
return
|
113
|
-
elsif character == '\\'
|
114
|
-
in_escape = true
|
115
|
-
# TODO: need an
|
116
|
-
# «elsif character == '@'»
|
117
|
-
# here to deal with package substitution in variable statements
|
118
|
-
else
|
119
|
-
new_string << character
|
120
|
-
last_was_escaped = false
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
if in_escape
|
125
|
-
yield 'ends in an incomplete escape sequence.'
|
126
|
-
return
|
127
|
-
elsif had_starting_quote
|
128
|
-
if last_was_escaped
|
129
|
-
yield 'has unbalanced double quotes (last quote was escaped).'
|
130
|
-
return
|
131
|
-
end
|
132
|
-
elsif ! last_was_escaped && ! had_starting_quote && last_character == %q<">
|
133
|
-
yield 'has unbalanced double quotes.'
|
134
|
-
return
|
135
|
-
end
|
136
|
-
|
137
|
-
string.replace(new_string)
|
138
|
-
|
139
|
-
return false
|
140
|
-
end
|
141
|
-
|
142
|
-
public
|
143
|
-
|
144
29
|
# This mess of getting these as a single array necessary is due to
|
145
30
|
# limitations of the "*" array splat operator in ruby v1.8.
|
146
31
|
def initialize(line_column, source_description)
|
@@ -151,6 +36,12 @@ class Fig::Statement
|
|
151
36
|
@source_description = source_description
|
152
37
|
end
|
153
38
|
|
39
|
+
# A name for this kind of Statement, usually a keyword for this statement as
|
40
|
+
# it appears in package definition files.
|
41
|
+
def statement_type()
|
42
|
+
raise NotImplementedError
|
43
|
+
end
|
44
|
+
|
154
45
|
# Block will receive a Statement.
|
155
46
|
def walk_statements(&block)
|
156
47
|
return
|
@@ -160,7 +51,15 @@ class Fig::Statement
|
|
160
51
|
raise NotImplementedError
|
161
52
|
end
|
162
53
|
|
163
|
-
|
54
|
+
# Returns a two element array containing the version and an explanation of
|
55
|
+
# why the version is necessary if the version is greater than 0.
|
56
|
+
def minimum_grammar_for_emitting_input()
|
57
|
+
raise NotImplementedError
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns a two element array containing the version and an explanation of
|
61
|
+
# why the version is necessary if the version is greater than 0.
|
62
|
+
def minimum_grammar_for_publishing()
|
164
63
|
raise NotImplementedError
|
165
64
|
end
|
166
65
|
|
@@ -10,15 +10,17 @@ class Fig::Statement; end
|
|
10
10
|
class Fig::Statement::Archive < Fig::Statement
|
11
11
|
include Fig::Statement::Asset
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
def initialize(line_column, source_description, url, glob_if_not_url)
|
13
|
+
def initialize(line_column, source_description, location, glob_if_not_url)
|
16
14
|
super(line_column, source_description)
|
17
15
|
|
18
|
-
@
|
16
|
+
@location = location
|
19
17
|
@glob_if_not_url = glob_if_not_url
|
20
18
|
end
|
21
19
|
|
20
|
+
def statement_type()
|
21
|
+
return 'archive'
|
22
|
+
end
|
23
|
+
|
22
24
|
def asset_name()
|
23
25
|
return standard_asset_name()
|
24
26
|
end
|
data/lib/fig/statement/asset.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
1
3
|
require 'fig/parser'
|
2
4
|
require 'fig/statement'
|
5
|
+
require 'fig/string_tokenizer'
|
3
6
|
require 'fig/url'
|
4
7
|
|
5
8
|
module Fig; end
|
@@ -7,7 +10,7 @@ class Fig::Statement; end
|
|
7
10
|
|
8
11
|
# Some sort of file to be included in a package.
|
9
12
|
module Fig::Statement::Asset
|
10
|
-
attr_reader :
|
13
|
+
attr_reader :location
|
11
14
|
|
12
15
|
def self.included(class_included_into)
|
13
16
|
class_included_into.extend(ClassMethods)
|
@@ -20,7 +23,7 @@ module Fig::Statement::Asset
|
|
20
23
|
end
|
21
24
|
|
22
25
|
def urls()
|
23
|
-
return [
|
26
|
+
return [location()]
|
24
27
|
end
|
25
28
|
|
26
29
|
def is_asset?()
|
@@ -28,57 +31,69 @@ module Fig::Statement::Asset
|
|
28
31
|
end
|
29
32
|
|
30
33
|
def requires_globbing?()
|
31
|
-
return glob_if_not_url? && ! Fig::URL.is_url?(
|
34
|
+
return glob_if_not_url? && ! Fig::URL.is_url?(location())
|
32
35
|
end
|
33
36
|
|
34
37
|
def standard_asset_name()
|
35
|
-
# Not so hot of an idea if the URL has query parameters
|
36
|
-
# going to fix this now.
|
37
|
-
|
38
|
-
end
|
38
|
+
# Not so hot of an idea if the location is a URL and has query parameters
|
39
|
+
# in it, but not going to fix this now.
|
40
|
+
basename = location().split('/').last
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
+
if Fig::URL.is_url? location
|
43
|
+
return CGI.unescape basename
|
44
|
+
end
|
42
45
|
|
43
|
-
|
44
|
-
|
46
|
+
return basename
|
47
|
+
end
|
45
48
|
|
46
|
-
|
47
|
-
return
|
49
|
+
def minimum_grammar_for_emitting_input()
|
50
|
+
return minimum_grammar_for_value location
|
51
|
+
end
|
48
52
|
|
49
|
-
|
53
|
+
def minimum_grammar_for_publishing()
|
54
|
+
return minimum_grammar_for_value asset_name
|
50
55
|
end
|
51
56
|
|
52
57
|
private
|
53
58
|
|
54
|
-
|
55
|
-
|
56
|
-
def validate_and_process_escapes_in_url!(url, &block)
|
57
|
-
was_in_single_quotes =
|
58
|
-
Fig::Statement.strip_quotes_and_process_escapes!(url, &block)
|
59
|
-
return if was_in_single_quotes.nil?
|
60
|
-
|
61
|
-
if url.include? '@'
|
62
|
-
yield %q<contains an "@", which isn't permitted in order to allow for package substitution.>
|
63
|
-
return
|
64
|
-
end
|
59
|
+
def minimum_grammar_for_value(value)
|
60
|
+
return [0] if value.nil?
|
65
61
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
62
|
+
if value =~ /\s/
|
63
|
+
return [1, 'contains whitespace']
|
64
|
+
end
|
70
65
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
66
|
+
# Can't have octothorpes anywhere in v0 due to comment stripping via
|
67
|
+
# regex.
|
68
|
+
if value =~ /#/
|
69
|
+
return [1, 'contains a "#" character']
|
70
|
+
end
|
71
|
+
|
72
|
+
if ! glob_if_not_url? && value =~ / ( [*?\[\]{}] ) /x
|
73
|
+
return [
|
74
|
+
1, %Q<contains a glob character ("#{$1}") which should not be globbed>
|
75
|
+
]
|
76
|
+
end
|
77
|
+
|
78
|
+
if value =~ / ( ["'<>|] ) /x
|
79
|
+
return [1, %Q<contains a "#{$1}" character>]
|
80
|
+
end
|
81
|
+
|
82
|
+
return [0]
|
83
|
+
end
|
84
|
+
|
85
|
+
module ClassMethods
|
86
|
+
def validate_and_process_escapes_in_location(location, &block)
|
87
|
+
tokenizer = Fig::StringTokenizer.new
|
88
|
+
tokenized_string = tokenizer.tokenize(location, &block)
|
89
|
+
return if ! tokenized_string
|
75
90
|
|
76
91
|
# "config" is a reasonable asset name, so we let that pass.
|
77
|
-
if Fig::Parser.strict_keyword?(
|
92
|
+
if Fig::Parser.strict_keyword?(tokenized_string.to_expanded_string)
|
78
93
|
yield 'is a keyword.'
|
79
94
|
end
|
80
95
|
|
81
|
-
return
|
96
|
+
return tokenized_string
|
82
97
|
end
|
83
98
|
end
|
84
99
|
end
|
@@ -13,11 +13,15 @@ class Fig::Statement::Command < Fig::Statement
|
|
13
13
|
@command = command
|
14
14
|
end
|
15
15
|
|
16
|
+
def statement_type()
|
17
|
+
return 'command'
|
18
|
+
end
|
19
|
+
|
16
20
|
def unparse_as_version(unparser)
|
17
21
|
return unparser.command(self)
|
18
22
|
end
|
19
23
|
|
20
|
-
def
|
21
|
-
return 0
|
24
|
+
def minimum_grammar_for_publishing()
|
25
|
+
return [0]
|
22
26
|
end
|
23
27
|
end
|
@@ -21,6 +21,10 @@ class Fig::Statement::Configuration < Fig::Statement
|
|
21
21
|
@statements = [overrides, others].flatten
|
22
22
|
end
|
23
23
|
|
24
|
+
def statement_type()
|
25
|
+
return 'config'
|
26
|
+
end
|
27
|
+
|
24
28
|
def command_statement
|
25
29
|
return statements.find do
|
26
30
|
|statement| statement.is_a?(Fig::Statement::Command)
|
@@ -39,7 +43,11 @@ class Fig::Statement::Configuration < Fig::Statement
|
|
39
43
|
return unparser.configuration(self)
|
40
44
|
end
|
41
45
|
|
42
|
-
def
|
43
|
-
return 0
|
46
|
+
def minimum_grammar_for_emitting_input()
|
47
|
+
return [0]
|
48
|
+
end
|
49
|
+
|
50
|
+
def minimum_grammar_for_publishing()
|
51
|
+
return [0]
|
44
52
|
end
|
45
53
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Fig; end
|
2
|
+
class Fig::Statement; end
|
3
|
+
|
4
|
+
# A statement that manipulates an environment variable.
|
5
|
+
module Fig::Statement::EnvironmentVariable
|
6
|
+
attr_reader :name, :value
|
7
|
+
|
8
|
+
def minimum_grammar_for_emitting_input()
|
9
|
+
return minimum_grammar()
|
10
|
+
end
|
11
|
+
|
12
|
+
def minimum_grammar_for_publishing()
|
13
|
+
return minimum_grammar()
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def minimum_grammar()
|
19
|
+
if value =~ /\s/
|
20
|
+
return [1, 'contains whitespace']
|
21
|
+
end
|
22
|
+
|
23
|
+
# Can't have octothorpes anywhere in v0 due to comment stripping via
|
24
|
+
# regex.
|
25
|
+
if value =~ /#/
|
26
|
+
return [1, 'contains a "#" character']
|
27
|
+
end
|
28
|
+
|
29
|
+
if value =~ / ( ["'] ) /x
|
30
|
+
return [1, %Q<contains a "#{$1}" character>]
|
31
|
+
end
|
32
|
+
|
33
|
+
return [0]
|
34
|
+
end
|
35
|
+
end
|
@@ -12,11 +12,15 @@ class Fig::Statement::GrammarVersion < Fig::Statement
|
|
12
12
|
@version = version
|
13
13
|
end
|
14
14
|
|
15
|
+
def statement_type()
|
16
|
+
return 'grammar'
|
17
|
+
end
|
18
|
+
|
15
19
|
def unparse_as_version(unparser)
|
16
20
|
return unparser.grammar_version(self)
|
17
21
|
end
|
18
22
|
|
19
|
-
def
|
20
|
-
return version
|
23
|
+
def minimum_grammar_for_publishing()
|
24
|
+
return [version]
|
21
25
|
end
|
22
26
|
end
|
@@ -23,6 +23,10 @@ class Fig::Statement::Include < Fig::Statement
|
|
23
23
|
@containing_package_descriptor = containing_package_descriptor
|
24
24
|
end
|
25
25
|
|
26
|
+
def statement_type()
|
27
|
+
return 'include'
|
28
|
+
end
|
29
|
+
|
26
30
|
def package_name
|
27
31
|
return @descriptor.name
|
28
32
|
end
|
@@ -66,8 +70,8 @@ class Fig::Statement::Include < Fig::Statement
|
|
66
70
|
return unparser.include(self)
|
67
71
|
end
|
68
72
|
|
69
|
-
def
|
70
|
-
return 0
|
73
|
+
def minimum_grammar_for_publishing()
|
74
|
+
return [0]
|
71
75
|
end
|
72
76
|
|
73
77
|
private
|
@@ -33,11 +33,15 @@ class Fig::Statement::Override < Fig::Statement
|
|
33
33
|
@version = version
|
34
34
|
end
|
35
35
|
|
36
|
+
def statement_type()
|
37
|
+
return 'override'
|
38
|
+
end
|
39
|
+
|
36
40
|
def unparse_as_version(unparser)
|
37
41
|
return unparser.override(self)
|
38
42
|
end
|
39
43
|
|
40
|
-
def
|
41
|
-
return 0
|
44
|
+
def minimum_grammar_for_publishing()
|
45
|
+
return [0]
|
42
46
|
end
|
43
47
|
end
|
data/lib/fig/statement/path.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'fig/statement'
|
2
|
+
require 'fig/statement/environment_variable'
|
2
3
|
|
3
4
|
module Fig; end
|
4
5
|
|
5
6
|
# A statement that specifies or modifies a path environment variable, e.g.
|
6
7
|
# "append", "path", "add" (though those are all synonyms).
|
7
8
|
class Fig::Statement::Path < Fig::Statement
|
9
|
+
include Fig::Statement::EnvironmentVariable
|
10
|
+
|
8
11
|
# We block single-quotes right now in order to allow for using them for
|
9
12
|
# quoting later.
|
10
13
|
VALUE_REGEX = %r< \A [^;:'"<>|\s]+ \z >x
|
@@ -27,8 +30,6 @@ class Fig::Statement::Path < Fig::Statement
|
|
27
30
|
return [variable, value]
|
28
31
|
end
|
29
32
|
|
30
|
-
attr_reader :name, :value
|
31
|
-
|
32
33
|
def initialize(line_column, source_description, name, value)
|
33
34
|
super(line_column, source_description)
|
34
35
|
|
@@ -36,6 +37,10 @@ class Fig::Statement::Path < Fig::Statement
|
|
36
37
|
@value = value
|
37
38
|
end
|
38
39
|
|
40
|
+
def statement_type()
|
41
|
+
return 'path'
|
42
|
+
end
|
43
|
+
|
39
44
|
def is_environment_variable?()
|
40
45
|
return true
|
41
46
|
end
|
@@ -43,10 +48,4 @@ class Fig::Statement::Path < Fig::Statement
|
|
43
48
|
def unparse_as_version(unparser)
|
44
49
|
return unparser.path(self)
|
45
50
|
end
|
46
|
-
|
47
|
-
def minimum_grammar_version_required()
|
48
|
-
# TODO: fix this once going through
|
49
|
-
# Statement.strip_quotes_and_process_escapes()
|
50
|
-
return 0
|
51
|
-
end
|
52
51
|
end
|