-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Refactor auto extension resolution to not use k6deps and esbuild #5320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
5c93d1d to
d738041
Compare
|
This likely should get more tests, and either drop the launcher.go and the old way or to further make it possible to use the old resolution method ... for now at least. But I would like some initial feedback and thoughts. |
internal/cmd/launcher.go
Outdated
| constraints := string(match[idxUseConstraints]) | ||
|
|
||
| if _, ok := deps[extension]; ok { | ||
| return deps, fmt.Errorf("already had a use directivce for %q", extension) |
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.
| return deps, fmt.Errorf("already had a use directivce for %q", extension) | |
| return deps, fmt.Errorf("already had a use directive for %q", extension) |
Is this printed to the user? Can we make it a bit more user friendly? I guess if this appears out of nowhere the user is not getting it fast.
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.
Please see it now.
| // TODO(@mstoykov) potentially figure out some less "exceptionl workflow" solution | ||
| type runDifferentBinaryError struct { | ||
| customBinary commandExecutor | ||
| } |
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.
To be honest, that approach seems it introduces not very linear logic which is difficult to follow and remember. I'd appreciate if we try to find a better way before merge it.
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 do agree with you which is why I left the comment.
Unfortunately having gone though doing the changes ... this seems like the most concise and not convuleted way to do it.
Effectively we want to stop executing the current workflow and run a new program.
Currently we use the fact that returning an error will do that, and we return errors from the different places where the source is loaded in the same way. They all propagate it backwards and then in the root command where nothing else will happen otherwise we check if it is the specific error and run the command, instead of errroring.
In all other cases all this backtracking will need to be codified, which likely will mean a lot more changes to signatures of functions and changes to run, cloud( and cloud run), archive, inspect and ... propagate it backwards? Have it run here and return backwards to stop?
The only other not very involved way I can see is to execute here , and return a "do nothing error", which seems worse as it is now an error you should propagate backwards but the root still needs to figure out it should not do anything with it.
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.
@mstoykov Can you open an issue and assign to the next milestone so we don't lose track of it, please?
65afd95 to
c8e52fa
Compare
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 just gave a first pass and centered my comments on the structure of the code.
I find it unintuitive that we use an error for actually handling the missing dependencies. I would prefer if we could split the logic and use the error for reporting and let someone else (the root command?) to handle it by attempting binary provisioning.
internal/cmd/root.go
Outdated
| var differentBinaryError runDifferentBinaryError | ||
|
|
||
| if errors.As(err, &differentBinaryError) { | ||
| err = differentBinaryError.customBinary.run(c.globalState) |
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 find getting the custom binary from the error unintuitive.
I would expect that the error was about missing dependencies and handle it here by attempting the binary provisioning. That would have a better separation of concerns between the error and how it is handled.
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 do agree on that part, but as I explain in https://raintank-corp.slack.com/archives/C07CJ4T7KN1/p1761206377837119?thread_ts=1761122691.317629&cid=C07CJ4T7KN1 , the alternative is probably twice as many changes if not more. and likely still very strange behaviours.
This way we unroll back to a state where I know nothing is happening and then running the new binary, if possible.
Please move the discussion there. And if this is the problem, I will do the changes, but given the time restrictions on v1.4.0 approaching, the complexity and the importantce of the changes, I would prefer to not keep adding stuff. I already had quite a lot of problems with stuff that ... I would define as implementation quirks
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 don't follow you. Unless I'm mistaken, the Slack thread you are pointing me to is about another unrelated topic (how we should resolve pragmas).
My comment is about the structure of the code. Regardless of how we find out the missing extensions, I think we should separate that from obtaining the binary.
And I think that discussion should happen here as it is related to the code.
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.
Aaah ,... sorry.
Do you mean like e48314e ?
|
I think I have gone through all the points and I also did some refactoring to make it easier to follow. |
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.
@mstoykov much better now, thanks for the effort 🙇
LGTM, as soon as we have a green CI.
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.
Thanks for the changes. I like this structure more. I left some comments, none of them blocking.
| return nil | ||
| } | ||
|
|
||
| func findDirectives(text []byte) []string { |
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.
What's the reason for not using regexp from k6deps for this analysis? wouldn't it be more compact?
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 needed to fix them which turned out to not work particularly well
- I ... did find they are slightly buggy in strange cases such as "use k6 with k6/x/sql with something" is ... .okay and it parsed it as "use k6 something" if I remember correctly
- I do not think it is more readable and I am pretty sure it is 1-2 lines shorter.
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.
3cca41f you can see that all the definitions are basically more than half the current implementation.
And I do not think I am the only person who thinks the regex are ... not exactly the easiest thing to debug.
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.
@mstoykov I didn't mean to ask for changes (I'm pretty sure I only submitted comments), so please ignore that. Github and its mysterious ways....
Co-authored-by: Ivan <[email protected]>
Co-authored-by: Ivan <[email protected]>
38432f1 to
ca4a183
Compare
What?
Reimplement auto extension resolution without using esbuild or k6deps, but the internal methods that k6 uses to load modules.
Why?
This removes the need for a separate project to have the same way to parse and understand imports and also double parsing everything.
Also fixing a number of bugs coming from this and removes the maintaince burden to keep both projects align.
Checklist
make check) and all pass.Checklist: Documentation (only for k6 maintainers and if relevant)
Please do not merge this PR until the following items are filled out.
Related PR(s)/Issue(s)
Based on #5240 and requires #5319 to have the same functionality as the same.
Fixes #5127
FIxes #5176
Fixes #5104
Closes #5102
Requirement for #5166 ( likely a future PR that refactors more of test_load.go)
Likely some updates to every other issue around automatic extension resolution as well.