Search code examples
jsonnet

Computed fields cannot access local variables?


I have the following block of code:

local tst = {
  postgres: {
    test: {
      // params: ['blahblah'],
    },
  },
};

{
  [if std.length(std.objectFields(tst)) > 0 then 'aws_db_parameter_group']: {
    ['pgsql_%s' % db]: {
      local database = tst.postgres[db],  // <--- Here's my local scope var
      name: 'pgsql_%s' % db,
      [if 'params' in tst.postgres[db] then 'parameter']: database.params,
    }
    for db in std.objectFields(if 'postgres' in tst then tst.postgres else {})
  },
}

Which works as expected:

> ./jsonnet tst.jsonnet
{
   "aws_db_parameter_group": {
      "pgsql_test": {
         "name": "pgsql_test"
      }
   }
}

However if I change the line:

[if 'params' in tst.postgres[db] then 'parameter']: database.params,

To:

[if 'params' in database then 'parameter']: database.params,

Jsonnet throws an error:

> ./jsonnet tst.jsonnet
STATIC ERROR: tst.jsonnet:14:23-31: Unknown variable: database

What am I doing wrong? Can I get around this?

> ./jsonnet --version
Jsonnet commandline interpreter v0.18.0

Solution

  • From what I've found (not an expert in jsonnet internals), you need to have computed fields variables "fully" finalized before entering the scope where you're using them.

    I your case, below fixes it:

    local tst = {
      postgres: {
        test: {
          params: ['blahblah'],
        },
        test_noparam: {
        },
      },
    };
    
    {
      [if std.length(std.objectFields(tst)) > 0 then 'aws_db_parameter_group']: {
        local database = tst.postgres[db],  // <--- Here's the local var, finalized in _upper_ scope
        ['pgsql_%s' % db]: {
          name: 'pgsql_%s' % db,
          [if 'params' in database then 'parameter']: database.params,
        }
        for db in std.objectFields(if 'postgres' in tst then tst.postgres else {})
      },
    }