-
Notifications
You must be signed in to change notification settings - Fork 62
Correct importer treatment of extvars and TLAs loaded from files #266
Correct importer treatment of extvars and TLAs loaded from files #266
Conversation
db03dc9 to
5da0ffd
Compare
|
Ah, the problem is that we're using the |
anguslees
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Matching on magic sentinel string values (extVarKindRE) feels fragile and surprising. Perhaps we could change the arg file names to absolute form as part of building the import statements (and then only attempt to parse importedFrom if the file arg is relative)? I don't know, but something else 😛
Do I understand you correctly that you'd prefer to resolve the file path against the current working directory when parsing the flags, so that we wind up with an absolute path from the start? If so, I'll try that tomorrow and see how it goes. Also, if I'm reading it right, the Go Jsonnet port bypasses explicit treatment of these strings by relying on |
|
@seh This uncovers two bugs actually:
|
They do make their way down into calls on the
Angus's suggestion above is an adaptation of what I implemented yesterday—namely, for these imports, use the process's current working directory as the "importedFrom" directory, in order to turn a relative file path into an absolute path fit for recording (temporarily) in a URL. It seems that with just these two importers as examples—the one in the Jsonnet Go port, and the I'm less sure how to accommodate URL-based importers, though; is it always the case that a "file" nominated on the command line for, say,
I take it that's an optimization, but that the current caching behavior is still correct. |
Instead, store the value as either an "import" or "importstr" statement, deferring to the Jsonnet VM's configured Importer to handle locationg and reading the resource.
When a Jsonnet consults an Importer for a path nominated by an external variable or top-level argument file-based command-line flag, the "importedFrom" parameter passed to the Importer.Import method is not a valid URL, but is instead a sentinel placeholder value. Detect these sentinel values and use the current working directory as the base URL instead when resolving relative import paths.
Well, these locations are used as caching keys, so if someone has a file at the absolute location "extvar:foo" and an extvar |
The API does not have any special notion of "file extVars". The option |
Ah, but here in kubecfg, we did just recently add these same command-line flags, and we do have a custom |
I see. It seems that it is implemented by putting the So it seems to me, that the main problem is handling of |
We can benefit from the "pflag.SliceValue" type introduced with this version.
|
What if we just passed What do you think? |
5da0ffd to
f49e8a0
Compare
|
Well, getting the tests in file show_test.go required hacking at the |
That would get us back to what I implemented in commit 2780af4, but instead of using that regular expression to match "importedFrom" for things like "<top-level-arg:...>," we'd instead look for the sentinel empty string. If the "importedFrom" parameter value is empty like that, we'd know that we need to fall back to using our default base (the current working directory for files, at least). Per @anguslees's suggestion, in commit 00054cc I moved that treatment out of the |
Yes. The important difference is that then it would be relying on a documented behavior. And the decision what "base" to use needs to be made somewhere. Importer seems like the right place to me.
This is quite an effective workaround, but there are two small problems:
|
There, we accept sth.jsonnet as a relative file path, but then use the current working directory to turn that into an absolute file path and frame it as a "file"-scheme URL for use by the
Oh, that would be wonderful too. I'm not arguing against that. I just don't expect that I can wait long enough for that change to be released, so I'm trying to get this change approved now, with what we understand to be true today. If this project can later upgrade its dependency on a go-jsonnet version that passes those empty strings through, I'd propose going back to an |
f49e8a0 to
1ac5ce3
Compare
I see that you do that if the user passes |
Oh, good point! In that case, the "importedFrom" value would once again be one of these "<extvar:...>" placeholders, and our |
@sbarzowski, do you intend to pursue this soon? Assuming that we won't see an implementation or release within a few days, @anguslees, are you willing to proceed with an intermediate solution here, with the intention to come back through and update it to play along with a change in the Jsonnet |
|
FWIW I'm fine with an intermediate solution |
|
@seh I want to fix the API soon, in a few days. I don't have any specific timeline for the release, but we had one quite recently on the 16th, so I would rather avoid rushing another one. |
|
Thank you for the update. Given that, are there any further suggestions from reviewers for what I should change here? I expect the most controversial part is resetting the flags on Once this one merges, I intend to submit an anticipatory patch for consideration that expects |
mkmik
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the lag, I'm back now.
Thanks also for the other improvements like proper use of %v in errors etc.
LGTM modulo a minor comment
| // won't try to glean from an extVar or TLA reference the context necessary to | ||
| // resolve a relative path. | ||
| path := kv[1] | ||
| if !filepath.IsAbs(path) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just use filepath.Abs?
func Abs(path string) (string, error)
Abs returns an absolute representation of path. If the path is not absolute
it will be joined with the current working directory to turn it into an
absolute path. The absolute path name for a given file is not guaranteed to
be unique. Abs calls Clean on the result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I plead ignorance. I had never noticed that function before.
We can use it here, removing a few lines, though in the future I expect that we'll want to grab the current working directory here once—as we do up at line 250—and use that path repeatedly in the Importer once it's been converted into a "file"-scheme URL.
In other words, I could remove lines 250 through 254 today, but I'll probably be adding them back once the expected change to the Jsonnet Importer interface contract arrives.
If we use filepath.Abs here, it determines the current working directory on each call, and makes this operation fallible as a result—as opposed to us getting this possibility for failure out of the way at lines 251-253.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, the implementation of filepath.Abs calls on filepath.unixAbs, whose implementation looks familiar!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, it does call Clean though. anyway, we'll going to iterate on that in the next PR.
Thank! merged
|
@mkmik, I've been testing a locally-built kubecfg with these features, and it's working well. Could we push a fresh release that includes this patch? If you'd like me to get more involved to be able to issue such releases for the project, let me know. |
See #271. |
See google/go-jsonnet#329 for a request for establishing this contract. |
|
See google/go-jsonnet#447 for further movement on this front. |
Here we correct a few capabilities exposed by the recent #265:
--ext-str-file,--ext-code-file,--tla-str-file, and--tla-code-fileflagsInstead, store the value as either an
importorimportstrstatement, deferring to the Jsonnet VM's configured Importer to handle locationg and reading the resource.When a Jsonnet consults an
Importerfor a path nominated by an external variable or top-level argument file-based command-line flag, the "importedFrom" parameter passed to theImporter.Importmethod is not a valid URL, but is instead a sentinel placeholder value. Detectthese sentinel values and use the current working directory as the base URL instead when resolving relative import paths.
NB: At the moment, the new test function
TestShowUsingExtVarFilesfails due to some interference with the use of environment variables in the siblingTestShowfunction. I haven't figured out why that's so yet.