Querying Deeper
If you've got a long chain of dependencies of packages, it can be challenging
to figure out where a particular setting came from. You can get more detail
from both --list-dependencies
and
--list-variables
by adding these options.
Unlike the default behavior which will only look at a single base configuration, this option will cause Fig to follow all of the dependencies using all the configurations in the base package. This will not follow all configurations in all depended upon packages, only the ones reachable by one of the configurations in the base package.
For a simple base package like
config default
set FOO=bing
set BAR=bang
include blah/1.2.3
end
config nondefault
set BAR=bong
set BAZ=beng
end
and package "blah" like
config default
FROM_B_DEFAULT=x
end
config nondefault
FROM_B_NONDEFAULT=x
end
running
fig --list-variables --list-all-configs
will give you
BAR
BAZ
FOO
FROM_B_DEFAULT
i.e. all of the variables that can be set via any dependency path starting with a configuration in the base package. You only get variable names and not values because walking a single path through all dependencies cannot be done.
Similarly, using fig --list-dependencies --list-all-configs
with a base
package containing
config default
include foo/1.2.3
end
config nondefault
include foo/4.5.6
end
will emit
foo/1.2.3
foo/4.5.6
Following the example from --list-dependencies
above, if you additionally
specify --list-tree
, you'll get a nested dependency tree:
fig --list-dependencies --list-tree A/1.2.3
A/1.2.3
B/2.3.4
D/4.5.6
C/3.4.5
D/4.5.6
If you don't specify a package descriptor, but you've got a package.fig
or
application.fig
file in the current directory with the same dependencies as
package A above, you'll get
fig --list-dependencies --list-tree
<unpublished>
B/2.3.4
D/4.5.6
C/3.4.5
D/4.5.6
For --list-variables
, if you have package A
config default
set A1=blah
set A2=blah
include C/1.2.3
include B/1.2.3
end
package B
config default
set B1=blah
set B2=blah
end
and package C
config default
set C1=blah
set C2=blah
end
and you run fig --list-variables --list-tree A/1.2.3
, you'll get
A/1.2.3
| A1 = blah
| A2 = blah
'---C/1.2.3
| C1 = blah
| C2 = blah
'---B/1.2.3
B1 = blah
B2 = blah
You can tell the difference between a set
statement and a
add
/append
/path
statement by the output indicating the behavior of the
latter kind of statement. E.g. for a application.fig
containing
config default
set FOO=bing
append BAR=bong
end
running fig --list-variables --list-tree
will get you
<unpublished>
BAR = bong:$BAR
FOO = bing
as a add
, append
, or path
statement will prepend the value to the
existing value of the variable.
Instead of --list-tree
you can use --graphviz
to get
DOT emitted. Save the output to a
file or redirect to a program that understands
Graphviz. Among the standard programs, dot
is most
likely the most useful to you.
fig ... --graphviz | dot -Tx11
You can get dependencies or variables out in programmatically usable forms
using --json
and --yaml
.
Using the A/B/C example packages from above, if you run fig --list-variables --json A/1.2.3
, you'll get
{
"name": "A",
"version": "1.2.3",
"config": "default",
"variables": [
{
"type": "set",
"name": "A1",
"value": "blah"
},
{
"type": "set",
"name": "A2",
"value": "blah"
}
],
"dependencies": [
{
"name": "C",
"version": "1.2.3",
"config": "default",
"variables": [
{
"type": "set",
"name": "C1",
"value": "blah"
},
{
"type": "set",
"name": "C2",
"value": "blah"
}
]
},
{
"name": "B",
"version": "1.2.3",
"config": "default",
"variables": [
{
"type": "set",
"name": "B1",
"value": "blah"
},
{
"type": "set",
"name": "B2",
"value": "blah"
}
]
}
]
}
Similarly, fig --list-variables --yaml A/1.2.3
results in
---
name: A
version: 1.2.3
config: default
variables:
- type: set
name: A1
value: blah
- type: set
name: A2
value: blah
dependencies:
- name: C
version: 1.2.3
config: default
variables:
- type: set
name: C1
value: blah
- type: set
name: C2
value: blah
- name: B
version: 1.2.3
config: default
variables:
- type: set
name: B1
value: blah
- type: set
name: B2
value: blah
Note that JSON is not very good for dealing with
DAGs. If you've got an
even mildly complicated set of dependencies, the results of --json
can have
significant amounts of duplicate data. If you can handle
YAML, prefer that to JSON.
Consider the following packages:
W:
config default
include X/1.2.3
include Y/1.2.3
end
X:
config default
include Z/1.2.3
end
Y:
config default
include Z/1.2.3
end
Z:
config default
end
Contrast the result of fig --list-dependencies --json W/1.2.3
:
{
"name": "W",
"version": "1.2.3",
"config": "default",
"dependencies": [
{
"name": "X",
"version": "1.2.3",
"config": "default",
"dependencies": [
{
"name": "Z",
"version": "1.2.3",
"config": "default"
}
]
},
{
"name": "Y",
"version": "1.2.3",
"config": "default",
"dependencies": [
{
"name": "Z",
"version": "1.2.3",
"config": "default"
}
]
}
]
}
with the result of fig --list-dependencies --yaml W/1.2.3
:
---
name: W
version: 1.2.3
config: default
dependencies:
- name: X
version: 1.2.3
config: default
dependencies:
- &1
name: Z
version: 1.2.3
config: default
- name: Y
version: 1.2.3
config: default
dependencies:
- *1
and notice that there's only one copy of the Z package in the YAML version.
If you use the --list-all-configs
option with --yaml
or --json
and there are multiple configs in your base package, the root of the output
will be an array instead of a dictionary/object.