Skip to content
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

Asyncify without topmost interface #95

Merged
merged 64 commits into from
Nov 12, 2023

Conversation

2colours
Copy link
Contributor

@2colours 2colours commented Sep 16, 2023

The second attempt, following #93

Long story short: I do think the approach was alright but given the test framework, basically it was a Russian roulette what tests could work, if at all.

This time around, I deliberately omitted the very part I started with last time so that the interface shown towards the executable scripts and the tests themselves would stay callback-based.

@2colours
Copy link
Contributor Author

So the first couple of functions could be changed no problem, without any test outage.

The big one was the wrapping of the run method of all commands - I isolated the failing tests because there are all sorts of weird interactions.

First, it would be great to fix these tests actually. I'm not sure if that's possible without altering the tests. As a final radical measure, I think these commands could get separate handling behind a wrapper so if all seems lost, maybe there is still a way to keep only these commands callback-based, which I think is still a win, if the basic idea was that the code is ugly. The vast majority of code could still be not-so-ugly, and these commands could rightfully shout "think twice before touching me".

Then, for the other commands, I still think gradually going towards the bottom is a workable paradigm. There can be problems with the mocking but ultimately, if one part is fully Promise-based and eventually asyncified, there will be just genuinely no reason to try to mock certain functions by changing their arguments and such...

@2colours
Copy link
Contributor Author

I noticed a few things and refined the strategy as well.

  • first, the commands that already work with the tests are processed
  • then I think the other couple of commands need to be fixed by reducing the tests until a single point of failure remains, solving that, and then gradually adding the tests back if need be
  • then lower layers of code can be changed; they will probably gradually allow the higher layers to be refined to a nicer code structure
  • the interface of many Promises (what is a value, what is an error) will have to change. I started with a "whenever it's not crystal clear, use the resolve path only" policy. I think I have been overdoing it. Currently, I think only the Promises that actually have to pass resolve or reject on are okay to do that (if at all...). This will have to be redone when I reach back to the higher layers

Anyway, for Commands, the workflow is pretty simple:

  1. check if some other command depends on directly calling this Command (with run). If it does, make sure it can be rewritten in a way that satisfies apm-cli and the other command as well, or else it may need to be skipped.
  2. set static promiseBased = true for the class
  3. go through the methods, checking their implementation to pick a promisification strategy
  4. check the callers of the methods and rewrite those calls appropriately
  5. as part of this process, rewrite the run method as well, check the tests, fix the mistakes...

@2colours
Copy link
Contributor Author

I reached a state where all tests succeed with slight alternations:

  1. some functions need to be mocked differently - this is pretty obvious
  2. the ultimate return value the callback obtains is sometimes downright undefined, not null - I think this is even desirable and there should be less explicit null returns but this is easy to twist in many ways

I would be worried about the install --json path; it's like a whole different command that is carried over to quite low layers of the same functions, and it is the reason why many installation methods need to produce values... I think it needs further testing at the very least; it would be nice to rework it once in the future.

@2colours
Copy link
Contributor Author

Now, this pull request has "officially" reached the state where (I think) everything that clearly needed an async-based implementation, got one.

The next - and arguably final - stage should consist of:

  • "integration testing", i.e actually trying out various functionality, at least with a sample check approach
  • refactoring of leftover stuff if we find such
  • finalizing the interfaces that this version of code provides, so typically deciding on how the commands work
    • currently, their return value is the error, if there is any
    • and apm-cli did remain callback-based because otherwise all the tests should have been rewritten
    • I don't like these two things, especially the former... but I think we could actually live with them for the time being, and do different PR's to mitigate them

@2colours 2colours marked this pull request as ready for review October 1, 2023 15:58
@2colours
Copy link
Contributor Author

2colours commented Oct 1, 2023

From now on, there are no planned modifications that I still wanted to do, only fixes, or, if it's decided that some interface modification is required in this PR, then that can be added. All in all, I think it's ready for review.

As I said, since the spec is far from exhaustive, some testing is required, others are of course more than welcome to join in with that.

Polgár Márton added 20 commits October 1, 2023 14:49
No functional changes so far.
No tests broke. This is a functional change but very much a simple and
basic transformation.
All tests succeed. This is a wrapper implementation, like for printVersions.
Under similar terms as the previous ones. Tests passing.
There are failing tests that I isolated in a spec2 folder.
- develop-spec seems like it "mocks out" the resolution of the Promise,
causing some tests to fail
- stars-spec explodes with a "trying to reopen HTTP port" error,
probably some cleanup section couldn't run
- test-spec mocks I/O of processes and for some reason, the
tests won't produce the right output
- unpublish-spec fails at the unpublishing itself,
there is a lot of mocking but the failure looks too legit nevertheless
- upgrade-spec first times out and then dies with the "HTTP port" error, like stars-spec
It seems that install-spec was the one that didn't close the server, causing the remaining
tests using a server to break.
And the polishment of the corresponding test which passes now. 🎉
getRepositoryUrl has a true resolve-reject interface, the rest always resolves,
mostly wrapped by the Promise constructor
All the previous tests pass still. Finally, a function that could be changed to
an async flow, rather than just wrapped into a Promise.
The calls have been modified appropriately.
Tests still pass. It's a really thin Promise wrapper on the existing code.
Tiny file, tiny wrapper, tests pass.
Tests pass, tiny wrapper of tiny command
A bit fatter wrapping for a bit fatter command. Tests are passing.
Tests passing, trivial wrapper used.
Tests passing. Trivial wrapper added.
Tests passing. Two of the three methods could immediately be turned into async 🎉
It was so small that it was easier to do than not do.
Only install.js was modified which is currently not tested.
Tests still passing. The main change is that printVersions in apm-cli could be promisified
as a result.
Tests passing. run could be asyncified right away. I still want to tackle
generateFromTemplate which is ugly.
Tests still passing. It was so banal that it could be asyncified right away.
As a positive side effect, linkPackage in develop.js doesn't have to be wrapped
with the Promise constructor anymore.
Polgár Márton added 13 commits October 1, 2023 14:49
This command is broken on master as well but install.js calls the rebuild
method so I went ahead and asyncified it.
It still doesn't work (I think the problem is related to asar and faulty
resolution of "resource paths") but the tests are still passing.
This is a cosmetic phase of the iterative development. I'm eliminating as
much of callbacks as possible to see what work is left.
All tests passing.
Similar to the last commit. All tests passing.
Similar to the previous two commits. All tests passing.
It seems to me that probably only request.js and login.js are still the old way...
Similar to the previous cosmetic changes. All tests still passing.
Similar to the previous ones. All tests passing.
*without the main user-facing interface because that's deliberately not a Node-style
callback. All tests are passing.
This is the main reason I didn't want to touch Login before. It wasn't as
scary as it first seemed.
All tests passing, the only thing left is the Login command itself.
All tests passing - but tests are too lenient because they don't actually
test the prompt path...
That seems to work, too.
The interface is still unmodified because this was the only command that
had separate error and return value.
Tests (and manual check) passes. Now the command has no special return value,
and getTokenOrLogin calls a method that can have one.
The recent PR pulsar-edit#100 made me want to check this command and I noticed
I messed up at two places to make this work.
Rather obvious fixes for a fortunate catch...
Now that everything is Promise-based (and anything new should also be), it's
pointless to keep an option for classes to avoid wrapping into Promises.
Nothing should be wrapped anymore.
All tests still passing. Some unused code and leftover wrapping removed.
@DeeDeeG
Copy link
Member

DeeDeeG commented Oct 1, 2023

Rebasing on top of master branch now that #100 is merged, to basically port #100's changes to this PR and sync everything. As was discussed here on GitHub and on the Discord.

Old commit of this branch just before I rebased: 9dd95c6
New commit after I rebased: 0e865d2

(We can always go back and retrieve the old version if needed for whatever reason. I pushed it to a branch at this repo, for now, just in case: https://github.com/pulsar-edit/ppm/tree/old-asyncify-without-top-pre-rebase)

NOTE: The GitHub UI will show icons for author and committer. It was not showing an author icon before, since the email being used to commit is apparently not configured on @2colours' GitHub account as owned by them. So, GitHub's UI is currently only showing the committer icon (me). But the git metadata is correct that @2colours authored it, and that I re-committed it during my rebase. So, no I didn't author all these commits, and I'm not the author in the metadata, I'm the committer.

Copy link
Member

@confused-Techie confused-Techie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wanna say this is some fantastic work! Seriously, huge undertaking and I'm very much impressed.

I've left a few comments around about improvements or questions, or even just some comments. So please address them when you've got the chance, but besides those few items overall this looks perfect, and as for the code side of this review, I'd say it's basically good to go!

With that I'll add I'm relying on the manual testing that @DeeDeeG has done, and the automated tests to point out any unknown flaws in the logic, but as for the code it looks identical and completely valid, so I think we are good to go there!

src/apm-cli.js Show resolved Hide resolved
src/apm.js Show resolved Hide resolved
src/auth.js Show resolved Hide resolved
src/apm.js Show resolved Hide resolved
src/ci.js Show resolved Hide resolved
src/enable.js Outdated Show resolved Hide resolved
src/fs.js Show resolved Hide resolved
src/git.js Show resolved Hide resolved
src/link.js Show resolved Hide resolved
src/install.js Outdated Show resolved Hide resolved
2colours and others added 3 commits October 18, 2023 04:03
Co-authored-by: confused_techie <dev@lhbasics.com>
Co-authored-by: confused_techie <dev@lhbasics.com>
Co-authored-by: confused_techie <dev@lhbasics.com>
@Spiker985
Copy link
Member

@DeeDeeG @confused-Techie Since you're more familiar with this PR, is this PR something that you believe we can get in before next release?

Looks like it may want a new review, confused

Copy link
Member

@confused-Techie confused-Techie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, I'm gonna add an approval on here, but do want to make a clarification.

I've reviewed only the code side of changes, ensuring accuracy, and coherence to how things previously functioned. Ensuring that the only essential changes were made, albeit with some tiny stylistic and quality of life improvements.

So the code itself looks good, my concerns have been addressed, and otherwise this PR looks incredibly solid.

But as for functionality, I'm trusting two things, one @DeeDeeG themselves having previously tested these changes, the author of this PR themselves also testing these changes, and lastly the fact that our specs are happy, and report running the exact same amount of tests as the most recent PRs here, indicating that not much has changed coverage wise (Hopefully).

With that said, I'll add my approval here, but would be more than happy to hear from @DeeDeeG about any of their concerns coverage or functionality wise, if they exist.

Otherwise I fully support us getting this in, and getting it updated in Pulsar itself

Copy link
Member

@DeeDeeG DeeDeeG left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested a bunch of stuff before, and the PR is frozen from any meaningful changes since then, so it still stands.

I may not have gotten to every subcommand, but I'm comfortable enough getting this into Rolling hopefully with a few days lead time before Regular. (Tangent: That timing would be kind of tight, and I don't want to rush people about it, to be honest. But this is a tad off-topic to this PR itself.)

If we would have to do a hotfix release of Pulsar to roll back ppm and do a "try two" of this PR (even if maintainers have to handle that) that is all doable.

So, at this point I can "lite approve" (meaning, despite best intentions, I didn't have time to review the code myself, so I am approving on a basis of being willing to troubleshoot and manage any issues post-merge.) Let's go for it, I think.

@DeeDeeG DeeDeeG merged commit 13fb284 into pulsar-edit:master Nov 12, 2023
8 of 11 checks passed
@DeeDeeG
Copy link
Member

DeeDeeG commented Nov 12, 2023

Thanks again @2colours for all the hard work on this! I am merging it now.

Hopefully some more async/await style code will make things a lot easier to read and deal with! Thanks!

And P.S. sorry the review took so long, as this was a rather large change, we want to be cautious, but it all looks good from everything I have seen so far! Much appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants