fig 0.1.62 → 0.1.64
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 +156 -0
- data/VERSION +1 -1
- data/bin/fig +9 -2
- data/bin/fig-debug +9 -2
- data/lib/fig/applicationconfiguration.rb +3 -2
- data/lib/fig/atexit.rb +37 -0
- data/lib/fig/backtrace.rb +23 -6
- data/lib/fig/command.rb +131 -31
- data/lib/fig/command/coveragesupport.rb +40 -0
- data/lib/fig/command/listing.rb +8 -8
- data/lib/fig/command/optionerror.rb +8 -0
- data/lib/fig/{options.rb → command/options.rb} +248 -144
- data/lib/fig/command/packageload.rb +161 -62
- data/lib/fig/configfileerror.rb +2 -0
- data/lib/fig/environment.rb +350 -246
- data/lib/fig/environmentvariables/casesensitive.rb +1 -1
- data/lib/fig/figrc.rb +78 -78
- data/lib/fig/grammar.treetop +204 -219
- data/lib/fig/log4rconfigerror.rb +2 -0
- data/lib/fig/operatingsystem.rb +382 -334
- data/lib/fig/package.rb +11 -33
- data/lib/fig/packagecache.rb +1 -1
- data/lib/fig/packagedescriptor.rb +103 -21
- data/lib/fig/packagedescriptorparseerror.rb +16 -0
- data/lib/fig/parser.rb +36 -19
- data/lib/fig/parserpackagebuildstate.rb +56 -0
- data/lib/fig/repository.rb +504 -259
- data/lib/fig/statement.rb +30 -12
- data/lib/fig/statement/archive.rb +8 -5
- data/lib/fig/statement/asset.rb +19 -0
- data/lib/fig/statement/command.rb +2 -2
- data/lib/fig/statement/configuration.rb +20 -20
- data/lib/fig/statement/include.rb +13 -34
- data/lib/fig/statement/override.rb +21 -7
- data/lib/fig/statement/path.rb +22 -2
- data/lib/fig/statement/resource.rb +14 -4
- data/lib/fig/statement/retrieve.rb +34 -4
- data/lib/fig/statement/set.rb +22 -2
- data/lib/fig/workingdirectorymaintainer.rb +197 -0
- data/lib/fig/workingdirectorymetadata.rb +45 -0
- metadata +52 -46
- data/lib/fig/retriever.rb +0 -141
- data/lib/fig/statement/publish.rb +0 -15
data/lib/fig/statement.rb
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
module Fig; end
|
2
2
|
|
3
|
-
# A statement within a package
|
3
|
+
# A statement within a package definition file (package.fig).
|
4
4
|
class Fig::Statement
|
5
|
-
|
5
|
+
ENVIRONMENT_VARIABLE_NAME_REGEX = %r< \A \w+ \z >x
|
6
|
+
|
7
|
+
attr_reader :line, :column, :source_description
|
8
|
+
|
9
|
+
def self.position_description(line, column, source_description)
|
10
|
+
if not line or not column
|
11
|
+
return '' if not source_description
|
12
|
+
|
13
|
+
return " (#{source_description})"
|
14
|
+
end
|
15
|
+
|
16
|
+
description = " (line #{line}, column #{column}"
|
17
|
+
if source_description
|
18
|
+
description << ", #{source_description}"
|
19
|
+
end
|
20
|
+
description << ')'
|
21
|
+
|
22
|
+
return description
|
23
|
+
end
|
6
24
|
|
7
25
|
# This mess of getting these as a single array necessary is due to
|
8
26
|
# limitations of the "*" array splat operator in ruby v1.8.
|
9
|
-
def initialize(line_column)
|
27
|
+
def initialize(line_column, source_description)
|
10
28
|
if line_column
|
11
29
|
@line, @column = *line_column
|
12
30
|
end
|
31
|
+
|
32
|
+
@source_description = source_description
|
13
33
|
end
|
14
34
|
|
15
35
|
# Block will receive a Statement.
|
@@ -17,13 +37,12 @@ class Fig::Statement
|
|
17
37
|
return
|
18
38
|
end
|
19
39
|
|
20
|
-
|
21
|
-
|
22
|
-
return
|
40
|
+
def urls()
|
41
|
+
return []
|
23
42
|
end
|
24
43
|
|
25
|
-
def
|
26
|
-
return
|
44
|
+
def is_asset?()
|
45
|
+
return false
|
27
46
|
end
|
28
47
|
|
29
48
|
# Returns a representation of the position of this statement, if the position
|
@@ -32,9 +51,8 @@ class Fig::Statement
|
|
32
51
|
# statement%{statement.position_string()}.>" and get nice looking output
|
33
52
|
# regardless of whether the position is actually known or not.
|
34
53
|
def position_string
|
35
|
-
return
|
36
|
-
|
37
|
-
|
38
|
-
return " (line #{@line}, column #{@column})"
|
54
|
+
return Fig::Statement.position_description(
|
55
|
+
@line, @column, @source_description
|
56
|
+
)
|
39
57
|
end
|
40
58
|
end
|
@@ -1,21 +1,24 @@
|
|
1
1
|
require 'fig/statement'
|
2
|
+
require 'fig/statement/asset'
|
2
3
|
|
3
4
|
module Fig; end
|
4
5
|
|
5
|
-
# Specifies an archive file (possibly via a URL) that is part of
|
6
|
+
# Specifies an archive file (possibly via a URL) that is part of a package.
|
6
7
|
#
|
7
8
|
# Differs from a Resource in that the contents will be extracted.
|
8
9
|
class Fig::Statement::Archive < Fig::Statement
|
10
|
+
include Fig::Statement::Asset
|
11
|
+
|
9
12
|
attr_reader :url
|
10
13
|
|
11
|
-
def initialize(line_column, url)
|
12
|
-
super(line_column)
|
14
|
+
def initialize(line_column, source_description, url)
|
15
|
+
super(line_column, source_description)
|
13
16
|
|
14
17
|
@url = url
|
15
18
|
end
|
16
19
|
|
17
|
-
def
|
18
|
-
return
|
20
|
+
def asset_name()
|
21
|
+
return standard_asset_name()
|
19
22
|
end
|
20
23
|
|
21
24
|
def unparse(indent)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Fig; end
|
2
|
+
class Fig::Statement; end
|
3
|
+
|
4
|
+
# Some sort of file to be included in a package.
|
5
|
+
module Fig::Statement::Asset
|
6
|
+
def urls()
|
7
|
+
return [ url() ]
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_asset?()
|
11
|
+
return true
|
12
|
+
end
|
13
|
+
|
14
|
+
def standard_asset_name()
|
15
|
+
# Not so hot of an idea if the URL has query parameters in it, but not
|
16
|
+
# going to fix this now.
|
17
|
+
return url().split('/').last()
|
18
|
+
end
|
19
|
+
end
|
@@ -7,8 +7,8 @@ module Fig; end
|
|
7
7
|
class Fig::Statement::Command < Fig::Statement
|
8
8
|
attr_reader :command
|
9
9
|
|
10
|
-
def initialize(line_column, command)
|
11
|
-
super(line_column)
|
10
|
+
def initialize(line_column, source_description, command)
|
11
|
+
super(line_column, source_description)
|
12
12
|
|
13
13
|
@command = command
|
14
14
|
end
|
@@ -3,22 +3,25 @@ require 'fig/statement/command'
|
|
3
3
|
|
4
4
|
module Fig; end
|
5
5
|
|
6
|
-
# A grouping of statements within a
|
6
|
+
# A grouping of statements within a package. May not be nested.
|
7
|
+
#
|
8
|
+
# Any processing of statements is guaranteed to hit any Overrides first.
|
7
9
|
class Fig::Statement::Configuration < Fig::Statement
|
8
10
|
attr_reader :name, :statements
|
9
11
|
|
10
|
-
def initialize(line_column, name, statements)
|
11
|
-
super(line_column)
|
12
|
+
def initialize(line_column, source_description, name, statements)
|
13
|
+
super(line_column, source_description)
|
12
14
|
|
13
15
|
@name = name
|
14
|
-
@statements = statements
|
15
|
-
end
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
overrides, others = statements.partition do
|
18
|
+
|statement| statement.is_a?(Fig::Statement::Override)
|
19
|
+
end
|
20
|
+
|
21
|
+
@statements = [overrides, others].flatten
|
19
22
|
end
|
20
23
|
|
21
|
-
def
|
24
|
+
def command_statement
|
22
25
|
return statements.find do
|
23
26
|
|statement| statement.is_a?(Fig::Statement::Command)
|
24
27
|
end
|
@@ -32,19 +35,16 @@ class Fig::Statement::Configuration < Fig::Statement
|
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
35
|
-
# Block will receive a Package and a Statement.
|
36
|
-
def walk_statements_following_package_dependencies(repository, package, configuration, &block)
|
37
|
-
@statements.each do |statement|
|
38
|
-
yield package, self, statement
|
39
|
-
statement.walk_statements_following_package_dependencies(
|
40
|
-
repository, package, self, &block
|
41
|
-
)
|
42
|
-
end
|
43
|
-
|
44
|
-
return
|
45
|
-
end
|
46
|
-
|
47
38
|
def unparse(indent)
|
48
39
|
unparse_statements(indent, "config #{@name}", @statements, 'end')
|
49
40
|
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def unparse_statements(indent, prefix, statements, suffix)
|
45
|
+
body =
|
46
|
+
@statements.map {|statement| statement.unparse(indent + ' ') }.join("\n")
|
47
|
+
|
48
|
+
return ["\n#{indent}#{prefix}", body, "#{indent}#{suffix}"].join("\n")
|
49
|
+
end
|
50
50
|
end
|
@@ -4,15 +4,22 @@ require 'fig/statement'
|
|
4
4
|
module Fig; end
|
5
5
|
|
6
6
|
# Dual role: "include :configname" incorporates one configuration into another;
|
7
|
-
# "include package[/version]" declares a dependency upon another package
|
7
|
+
# "include package[/version]" declares a dependency upon another package (with
|
8
|
+
# incorporation of the "default" configuration from that other package if no
|
9
|
+
# ":configname" is specified.
|
8
10
|
class Fig::Statement::Include < Fig::Statement
|
9
|
-
attr_reader :descriptor, :
|
11
|
+
attr_reader :descriptor, :containing_package_descriptor
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
+
# Centralized definition of requirements for descriptors for include
|
14
|
+
# statements.
|
15
|
+
def self.parse_descriptor(raw_string, options = {})
|
16
|
+
return Fig::PackageDescriptor.parse(raw_string, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(line_column, source_description, descriptor, containing_package_descriptor)
|
20
|
+
super(line_column, source_description)
|
13
21
|
|
14
22
|
@descriptor = descriptor
|
15
|
-
@overrides = overrides
|
16
23
|
@containing_package_descriptor = containing_package_descriptor
|
17
24
|
end
|
18
25
|
|
@@ -55,35 +62,12 @@ class Fig::Statement::Include < Fig::Statement
|
|
55
62
|
)
|
56
63
|
end
|
57
64
|
|
58
|
-
# Block will receive a Package and a Statement.
|
59
|
-
def walk_statements_following_package_dependencies(
|
60
|
-
repository, package, configuration, &block
|
61
|
-
)
|
62
|
-
referenced_package = nil
|
63
|
-
if package_name()
|
64
|
-
referenced_package = repository.get_package(descriptor())
|
65
|
-
else
|
66
|
-
referenced_package = package
|
67
|
-
end
|
68
|
-
|
69
|
-
configuration = referenced_package[referenced_config_name()]
|
70
|
-
|
71
|
-
yield referenced_package, configuration
|
72
|
-
configuration.walk_statements_following_package_dependencies(
|
73
|
-
repository, referenced_package, nil, &block
|
74
|
-
)
|
75
|
-
|
76
|
-
return
|
77
|
-
end
|
78
|
-
|
79
65
|
def unparse(indent)
|
80
66
|
text = ''
|
81
67
|
text += package_name() if package_name()
|
82
68
|
text += "/#{version()}" if version()
|
83
69
|
text += ":#{config_name()}" if config_name()
|
84
|
-
|
85
|
-
text += override.unparse
|
86
|
-
end
|
70
|
+
|
87
71
|
return "#{indent}include #{text}"
|
88
72
|
end
|
89
73
|
|
@@ -94,11 +78,6 @@ class Fig::Statement::Include < Fig::Statement
|
|
94
78
|
end
|
95
79
|
|
96
80
|
def referenced_version(containing_package, backtrace)
|
97
|
-
overrides().each do
|
98
|
-
|override|
|
99
|
-
backtrace.add_override(override.package_name(), override.version())
|
100
|
-
end
|
101
|
-
|
102
81
|
package_name = nil
|
103
82
|
original_version = nil
|
104
83
|
if package_name()
|
@@ -3,24 +3,38 @@ require 'fig/statement'
|
|
3
3
|
|
4
4
|
module Fig; end
|
5
5
|
|
6
|
-
# Overrides one package version dependency with another
|
7
|
-
# statement.
|
6
|
+
# Overrides one package version dependency with another.
|
8
7
|
#
|
9
|
-
#
|
8
|
+
# config whatever
|
9
|
+
# override somedependency/3.2.6
|
10
|
+
# end
|
10
11
|
#
|
11
12
|
# indicates that, regardless of which version of somedependency the blah
|
12
13
|
# package says it needs, the blah package will actually use v3.2.6.
|
13
14
|
class Fig::Statement::Override < Fig::Statement
|
14
15
|
attr_reader :package_name, :version
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
# Centralized definition of requirements for descriptors for override
|
18
|
+
# statements.
|
19
|
+
def self.parse_descriptor(raw_string, options = {})
|
20
|
+
filled_in_options = {}
|
21
|
+
filled_in_options.merge!(options)
|
22
|
+
filled_in_options[:name] = :required
|
23
|
+
filled_in_options[:version] = :required
|
24
|
+
filled_in_options[:config] = :forbidden
|
25
|
+
|
26
|
+
return Fig::PackageDescriptor.parse(raw_string, filled_in_options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(line_column, source_description, package_name, version)
|
30
|
+
super(line_column, source_description)
|
18
31
|
|
19
32
|
@package_name = package_name
|
20
33
|
@version = version
|
21
34
|
end
|
22
35
|
|
23
|
-
def unparse()
|
24
|
-
return
|
36
|
+
def unparse(indent)
|
37
|
+
return "#{indent}override " +
|
38
|
+
Fig::PackageDescriptor.format(@package_name, @version, nil)
|
25
39
|
end
|
26
40
|
end
|
data/lib/fig/statement/path.rb
CHANGED
@@ -5,10 +5,30 @@ module Fig; end
|
|
5
5
|
# A statement that specifies or modifies a path environment variable, e.g.
|
6
6
|
# "append", "path", "add" (though those are all synonyms).
|
7
7
|
class Fig::Statement::Path < Fig::Statement
|
8
|
+
VALUE_REGEX = %r< \A [^;:"<>|\s]+ \z >x
|
9
|
+
ARGUMENT_DESCRIPTION =
|
10
|
+
%q[The value must look like "NAME=VALUE". VALUE cannot contain any of ";:<>|", double quotes, or whitespace.]
|
11
|
+
|
12
|
+
# Yields on error.
|
13
|
+
def self.parse_name_value(combined)
|
14
|
+
variable, value = combined.split("=")
|
15
|
+
|
16
|
+
if variable !~ ENVIRONMENT_VARIABLE_NAME_REGEX
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
|
20
|
+
value = '' if value.nil?
|
21
|
+
if value !~ VALUE_REGEX
|
22
|
+
yield
|
23
|
+
end
|
24
|
+
|
25
|
+
return [variable, value]
|
26
|
+
end
|
27
|
+
|
8
28
|
attr_reader :name, :value
|
9
29
|
|
10
|
-
def initialize(line_column, name, value)
|
11
|
-
super(line_column)
|
30
|
+
def initialize(line_column, source_description, name, value)
|
31
|
+
super(line_column, source_description)
|
12
32
|
|
13
33
|
@name = name
|
14
34
|
@value = value
|
@@ -1,4 +1,6 @@
|
|
1
|
+
require 'fig/repository'
|
1
2
|
require 'fig/statement'
|
3
|
+
require 'fig/statement/asset'
|
2
4
|
|
3
5
|
module Fig; end
|
4
6
|
|
@@ -6,16 +8,24 @@ module Fig; end
|
|
6
8
|
#
|
7
9
|
# Differs from an Archive in that the contents will not be extracted.
|
8
10
|
class Fig::Statement::Resource < Fig::Statement
|
11
|
+
include Fig::Statement::Asset
|
12
|
+
|
9
13
|
attr_reader :url
|
10
14
|
|
11
|
-
def initialize(line_column, url)
|
12
|
-
super(line_column)
|
15
|
+
def initialize(line_column, source_description, url)
|
16
|
+
super(line_column, source_description)
|
13
17
|
|
14
18
|
@url = url
|
15
19
|
end
|
16
20
|
|
17
|
-
def
|
18
|
-
|
21
|
+
def asset_name()
|
22
|
+
if Fig::Repository.is_url?(url())
|
23
|
+
return standard_asset_name()
|
24
|
+
end
|
25
|
+
|
26
|
+
# This resource will end up being bundled with others and will not live in
|
27
|
+
# the package by itself.
|
28
|
+
return nil
|
19
29
|
end
|
20
30
|
|
21
31
|
def unparse(indent)
|
@@ -1,16 +1,46 @@
|
|
1
|
+
require 'fig/logging'
|
1
2
|
require 'fig/statement'
|
2
3
|
|
3
4
|
module Fig; end
|
4
5
|
|
5
|
-
# Specifies
|
6
|
+
# Specifies that files from a package should be copied into the current
|
7
|
+
# directory when an environment variable has its value changed.
|
6
8
|
class Fig::Statement::Retrieve < Fig::Statement
|
7
|
-
attr_reader
|
9
|
+
attr_reader :var, :path
|
8
10
|
|
9
|
-
def initialize(line_column, var, path)
|
10
|
-
super(line_column)
|
11
|
+
def initialize(line_column, source_description, var, path)
|
12
|
+
super(line_column, source_description)
|
11
13
|
|
12
14
|
@var = var
|
13
15
|
@path = path
|
16
|
+
|
17
|
+
# Yeah, it's not cross-platform, but File doesn't have an #absolute? method
|
18
|
+
# and this is better than nothing.
|
19
|
+
if path =~ %r< ^ / >x
|
20
|
+
Fig::Logging.warn(
|
21
|
+
%Q<The retrieve path "#{path}"#{position_string()} looks like it is intended to be absolute; retrieve paths are always treated as relative.>
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def loaded_but_not_referenced?()
|
27
|
+
return added_to_environment? && ! referenced?
|
28
|
+
end
|
29
|
+
|
30
|
+
def added_to_environment?()
|
31
|
+
return @added_to_environment
|
32
|
+
end
|
33
|
+
|
34
|
+
def added_to_environment(yea_or_nay)
|
35
|
+
@added_to_environment = yea_or_nay
|
36
|
+
end
|
37
|
+
|
38
|
+
def referenced?()
|
39
|
+
return @referenced
|
40
|
+
end
|
41
|
+
|
42
|
+
def referenced(yea_or_nay)
|
43
|
+
@referenced = yea_or_nay
|
14
44
|
end
|
15
45
|
|
16
46
|
def unparse(indent)
|
data/lib/fig/statement/set.rb
CHANGED
@@ -4,10 +4,30 @@ module Fig; end
|
|
4
4
|
|
5
5
|
# A statement that sets the value of an environment variable.
|
6
6
|
class Fig::Statement::Set < Fig::Statement
|
7
|
+
VALUE_REGEX = %r< \A \S* \z >x
|
8
|
+
ARGUMENT_DESCRIPTION =
|
9
|
+
%q<The value must look like "NAME=VALUE", though VALUE can be empty.>
|
10
|
+
|
11
|
+
# Yields on error.
|
12
|
+
def self.parse_name_value(combined)
|
13
|
+
variable, value = combined.split("=")
|
14
|
+
|
15
|
+
if variable !~ ENVIRONMENT_VARIABLE_NAME_REGEX
|
16
|
+
yield
|
17
|
+
end
|
18
|
+
|
19
|
+
value = '' if value.nil?
|
20
|
+
if value !~ VALUE_REGEX
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
|
24
|
+
return [variable, value]
|
25
|
+
end
|
26
|
+
|
7
27
|
attr_reader :name, :value
|
8
28
|
|
9
|
-
def initialize(line_column, name, value)
|
10
|
-
super(line_column)
|
29
|
+
def initialize(line_column, source_description, name, value)
|
30
|
+
super(line_column, source_description)
|
11
31
|
|
12
32
|
@name = name
|
13
33
|
@value = value
|