CertainLach/jrsonnet

'no such field' error

Duologic opened this issue · 12 comments

I have a project that does some meta programming in jsonnet and it fails with an error when using jrsonnet, it works with the Go/C++ jsonnet.

Steps to reproduce:

$ jb init && jb install github.com/crdsonnet/kube-state-metrics-libsonnet/ksm-custom
$ curl -sL https://github.com/CertainLach/jrsonnet/releases/download/v0.5.0-pre5-test/jrsonnet-linux-amd64 -O
$ chmod +x ./jrsonnet-linux-amd64
$ ./jrsonnet-linux-amd64 -J vendor -S -c -m docs/ \
      --exec "(import 'doc-util/main.libsonnet').render(import 'ksm-custom/main.libsonnet')"

Output:

no such field: customResourceStateMetrics
    vendor/github.com/crdsonnet/kube-state-metrics-libsonnet/ksm-custom/main.libsonnet:16:8-42: field <customResourceStateMetrics> access
    <cmdline>:1:43-78:                                                                          import "ksm-custom/main.libsonnet"
    vendor/github.com/jsonnet-libs/docsonnet/doc-util/render.libsonnet:401:35-39:               variable <obj> access
    vendor/github.com/jsonnet-libs/docsonnet/doc-util/render.libsonnet:348:27-31:               variable <obj> access
    <std>:0:0:                                                                                  variable <o> access
    argument <obj> evaluation
    <std>:0:0:                                                                                  function <builtin_object_fields_ex> call
    vendor/github.com/jsonnet-libs/docsonnet/doc-util/render.libsonnet:348:7-32:                function <objectFieldsAll> call
    argument <arr> evaluation
    vendor/github.com/jsonnet-libs/docsonnet/doc-util/render.libsonnet:271:6-271:7:             function <builtin_foldl> call
    vendor/github.com/jsonnet-libs/docsonnet/doc-util/render.libsonnet:401:22-40:               function <prepare> call
    vendor/github.com/jsonnet-libs/docsonnet/doc-util/render.libsonnet:381:21-29:               variable <package> access
    argument <x> evaluation
    vendor/github.com/jsonnet-libs/docsonnet/doc-util/render.libsonnet:381:10-42:               function <builtin_length> call
    vendor/github.com/jsonnet-libs/docsonnet/doc-util/render.libsonnet:381:14-381:15:           if condition
    vendor/github.com/jsonnet-libs/docsonnet/doc-util/render.libsonnet:401:5-41:                function <renderFiles> call
    <cmdline>:1:1-79:                                                                           function <render> call

I also tried with 0.4.2, same result.

Here is a similar error on a different project that uses the same meta programming library:

Steps to reproduce:

jb init && jb install github.com/grafana/grafonnet/examples/simple@main
curl -sL https://github.com/CertainLach/jrsonnet/releases/download/v0.5.0-pre5-test/jrsonnet-linux-amd64 -O
chmod +x ./jrsonnet-linux-amd64
./jrsonnet-linux-amd64 -J vendor vendor/simple/main.libsonnet

Output:

no such field: withTitle
There is fields with similar names present: withTemplateVariables, withTemplateVariablesMixin, withPanels
    vendor/github.com/grafana/grafonnet/grafonnet-base/veneer/dashboard.libsonnet:15:7-22: field <withTitle> access
    vendor/github.com/grafana/grafonnet/examples/simple/main.libsonnet:3:1-35:             function <new> call

I'll have a look at how I can create a minimally reproducible example.

There is something odd about those generated .withField methods; I can't figure out from where they are coming in the dashboard.new call, even when looking at the grafonnet code myself.

The functions are rendered at runtime with CRDsonnet.

Very simple representation of how this works:

local fields = [
  'title',
  'description',
];

local lib = {
  [name](value): {
    [name]: value,
  }
  for name in fields
};

lib.title('title')
+ lib.description('desc')

The functions are rendered at runtime. The fields come from a JSON Schema so can also be arbitrary.

Ha, there is the minimally reproducible example, here's the output I get with jrsonnet:

syntax error, expected one of one of "(", ".", "[", "{", "}", <binary op>, <whitespace>, got "f"
    /tmp/tmp.Jbzfh2GgCB/a.jsonnet:10:3

Nope, this is a parsing issue, caused by jrsonnet not figuring this is not an object, but object comprehension, which is fixed on master.

Running `target/debug/jrsonnet -e 'local fields = [
  '\''title'\'',
  '\''description'\'',
];

local lib = {
  [name](value): {
    [name]: value,
  }
  for name in fields
};

lib.title('\''title'\'')
+ lib.description('\''desc'\'')'`
{
   "description": "desc",
   "title": "title"
}

Aha, got it.
jb init && jb install github.com/grafana/grafonnet/examples/simple@main
Works on master branch too.

I don't know what the cause of this issue was, but there were some spec compatibility fixes, regarding lazy field evaluation, between pre5 and pre8.
I think self was becoming a fixed point before generated functions were added.

Great, seems to work.

For the sake of being closing the loop, I do get another unrelated error:

runtime error: std.thisFile is deprecated, to enable its support in jrsonnet - recompile it with "legacy-this-file" support.

🤷 I wasn't aware it was being deprecated.

It's not, but... google/jsonnet#838

It is quirky, and in the case of jrsonnet, many usages of this function (Current file path for std.native functions) may be replaced with better alternatives.

I should build it by default in releases, though, this deprecation is mostly for using jrsonnet as a library.

Cheers, just found that issue too, I've found that feature quite useful actually, so I'd be on the 'Let's keep it' side. 😇

thisFile will be enabled by default in the next release.