Skip to content
Elliot Shank edited this page May 16, 2018 · 1 revision

Delving 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.

--list-all-configs, a.k.a. "What's everything I can possibly get?"

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

--list-tree, a.k.a. "Hey, where'd that come from?"

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.

--graphviz, a.k.a. "ASCII art is boring, give me something prettier."

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

--json and --yaml, a.k.a. "I don't care how it looks; I need to actually process this stuff."

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.

Clone this wiki locally