fig 0.1.77 → 0.1.79

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/Changes +58 -1
  2. data/bin/fig +1 -1
  3. data/lib/fig.rb +1 -1
  4. data/lib/fig/command.rb +3 -3
  5. data/lib/fig/command/action/dump_package_definition_parsed.rb +5 -4
  6. data/lib/fig/command/action/list_variables/all_configs.rb +2 -5
  7. data/lib/fig/command/action/publish_local.rb +1 -1
  8. data/lib/fig/command/action/role/list_variables_in_a_tree.rb +2 -5
  9. data/lib/fig/command/action/run_command_line.rb +10 -3
  10. data/lib/fig/command/action/run_command_statement.rb +1 -1
  11. data/lib/fig/command/options.rb +8 -7
  12. data/lib/fig/command/options/parser.rb +1 -1
  13. data/lib/fig/environment_variables/case_insensitive.rb +1 -1
  14. data/lib/fig/environment_variables/case_sensitive.rb +1 -1
  15. data/lib/fig/figrc.rb +10 -10
  16. data/lib/fig/{not_found_error.rb → file_not_found_error.rb} +1 -1
  17. data/lib/fig/grammar/v0.rb +174 -173
  18. data/lib/fig/grammar/v0.treetop +27 -21
  19. data/lib/fig/grammar/v1.rb +477 -171
  20. data/lib/fig/grammar/v1.treetop +34 -22
  21. data/lib/fig/operating_system.rb +139 -60
  22. data/lib/fig/package.rb +8 -4
  23. data/lib/fig/package_definition_text_assembler.rb +31 -23
  24. data/lib/fig/parser.rb +3 -5
  25. data/lib/fig/parser_package_build_state.rb +15 -14
  26. data/lib/fig/repository.rb +41 -28
  27. data/lib/fig/repository_package_publisher.rb +20 -25
  28. data/lib/fig/runtime_environment.rb +136 -87
  29. data/lib/fig/statement.rb +15 -116
  30. data/lib/fig/statement/archive.rb +6 -4
  31. data/lib/fig/statement/asset.rb +50 -35
  32. data/lib/fig/statement/command.rb +6 -2
  33. data/lib/fig/statement/configuration.rb +10 -2
  34. data/lib/fig/statement/environment_variable.rb +35 -0
  35. data/lib/fig/statement/grammar_version.rb +6 -2
  36. data/lib/fig/statement/include.rb +6 -2
  37. data/lib/fig/statement/override.rb +6 -2
  38. data/lib/fig/statement/path.rb +7 -8
  39. data/lib/fig/statement/resource.rb +7 -3
  40. data/lib/fig/statement/retrieve.rb +10 -2
  41. data/lib/fig/statement/set.rb +7 -8
  42. data/lib/fig/string_tokenizer.rb +195 -0
  43. data/lib/fig/tokenized_string.rb +22 -0
  44. data/lib/fig/tokenized_string/plain_segment.rb +24 -0
  45. data/lib/fig/tokenized_string/token.rb +18 -0
  46. data/lib/fig/unparser.rb +84 -1
  47. data/lib/fig/unparser/v0.rb +4 -0
  48. data/lib/fig/unparser/v1.rb +7 -7
  49. data/lib/fig/url.rb +12 -1
  50. data/lib/fig/{url_access_error.rb → url_access_disallowed_error.rb} +2 -2
  51. metadata +129 -128
  52. data/lib/fig/grammar/v0_asset_location.rb +0 -162
  53. data/lib/fig/grammar/v0_ish.rb +0 -1356
  54. data/lib/fig/grammar/v1_asset_location.rb +0 -162
  55. data/lib/fig/grammar/v2.rb +0 -1478
@@ -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
- def minimum_grammar_version_required()
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
- attr_reader :url
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
- @url = url
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
@@ -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 :url
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 [ url() ]
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?(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 in it, but not
36
- # going to fix this now.
37
- return url().split('/').last()
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
- def minimum_grammar_version_required()
41
- return 1 if url =~ /\s/
42
+ if Fig::URL.is_url? location
43
+ return CGI.unescape basename
44
+ end
42
45
 
43
- # Can't have octothorpes anywhere in v0 due to comment stripping via regex.
44
- return 1 if url =~ /#/
46
+ return basename
47
+ end
45
48
 
46
- # If we shouldn't glob, but we've got glob characters...
47
- return 1 if ! glob_if_not_url? && url =~ /[*?\[\]{}]/
49
+ def minimum_grammar_for_emitting_input()
50
+ return minimum_grammar_for_value location
51
+ end
48
52
 
49
- return 0
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
- module ClassMethods
55
- # Modifies the parameter to deal with quoting, escaping.
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
- if url =~ / ( ["<>|] ) /x
67
- yield %Q<contains a "#{$1}", which isn't permitted because Windows doesn't allow it in file names.>
68
- return
69
- end
62
+ if value =~ /\s/
63
+ return [1, 'contains whitespace']
64
+ end
70
65
 
71
- if url =~ / ( ' ) /x
72
- yield %Q<contains a "#{$1}", which isn't permitted to allow for future grammar expansion.>
73
- return
74
- end
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?(url)
92
+ if Fig::Parser.strict_keyword?(tokenized_string.to_expanded_string)
78
93
  yield 'is a keyword.'
79
94
  end
80
95
 
81
- return ! was_in_single_quotes
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 minimum_grammar_version_required()
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 minimum_grammar_version_required()
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 minimum_grammar_version_required()
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 minimum_grammar_version_required()
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 minimum_grammar_version_required()
41
- return 0
44
+ def minimum_grammar_for_publishing()
45
+ return [0]
42
46
  end
43
47
  end
@@ -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