-
-
Notifications
You must be signed in to change notification settings - Fork 35
improvement: within tests and docs #267
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: main
Are you sure you want to change the base?
improvement: within tests and docs #267
Conversation
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.
Looks good 👍
25bbe87
to
91c572c
Compare
First time doing a docs guide. 🐛 Tried to keep it simple and concise. But I'm guessing this could be expanded to cover more real world examples. 🤔 |
|> Igniter.Project.Module.find_and_update_module!(SomeModule, fn zipper -> | ||
zipper | ||
|> within!(fn zipper -> | ||
pred = &match?(%Zipper{node: {:alias, _, _}}, &1) |
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.
We never really want to match on the zipper node if we can avoid it. For this example I'd pick something exactly matching for simplicity, like Igniter.Code.Common.nodes_equal?(zipper, Some.Module)
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.
Ah, ignore that, use Igniter.Code.Function.function_call?(zipper, :alias, 1)
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.
Even better:
Igniter.Code.Function.function_call?(zipper, :alias, 1, &Igniter.Code.Function.argument_equals?(&1, 0, The.Module.To.Replace)
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.
Your example using remove
will actually remove all aliases from the module, so that's why you want to be as specific as possible :).
The way I would typically recommend doing it is instead of using remove and add, you would move to the location of the node you want to modify and then replace that node.
case move_to_my_alias(zipper) do
{:ok, zipper} ->
{:ok, Igniter.Code.Common.replace_code(zipper, "import Some.Example, only: [:function]")}
:error ->
{:ok, zipper}
end
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 knew my way wasn't the right way 😂 But this way I'll learn the right way. 💯
@@ -0,0 +1,100 @@ | |||
# Writing Installers |
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.
Lets call this guide "writing installers & generators".
The logic is essentially the same, the only thing is that if your task is called <your_library>.install
then it will be invoked when mix igniter.install
is called.
## Fetching Dependency | ||
|
||
```elixir | ||
if Igniter.Project.Deps.has_dep?(igniter, :my_dep) do |
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.
So you don't have to do this typically. I'd say let's remove this example. If your installer should install additional packages or add additional dependencies, that should be configured in the installer. i.e installs: [{:other_dep, ...}], adds_deps: [{:other_dep2, ...}]
.
You don't need to add the specific dep that you are installing, as igniter handles that.
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.
🤔
When I comment out fetch_dep
which does above and do in info:
adds_deps: [{:routex, "~> 1.1"}],
installs: [{:routex, "~> 1.1"}],
No changes detected on assert_has_patch("mix.exs", ...)
Refering to this
Am I missing something? :thinkies:
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.
In tests we use compose_task
which does not call the full installer. but when using igniter.install
it will.
end) | ||
``` | ||
|
||
In the function block use [`within/2`](https://hexdocs.pm/igniter/Igniter.Code.Common.html#within/2) to do multiple modifications. Find the part you want to change and modify 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 like this tip, but let's maybe put it in its own section called like "making multiple modifications to a zipper"? Something good to describe also is the general concept of:
Igniter provides a high level API for working with a data structure called a "zipper". This data structure is defined by sourceror (link to sourceror), and at a certain level of generator complexity, you will inevitably end up working with zippers. We recommend reading through sourcerer's documentation. While we provide many tools for working with source code (Igniter.Code.*
, or working with project level concepts (Igniter.Project.*
), you may find yourself needing to use functions from Sourceror.Zipper
. This is normal. We provide high level wrappers around many sourceror operations that are "smart" and handle various edge cases and source code formats for you, but not every function from Sourceror.Zipper
needs a corresponding function from Igniter
.
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.
So much to learn 🧠 I should put this back to draft. ✔️
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.
You're doing great 😄 This is an important guide to get right and I'm grateful you're putting in the effort here 🙇
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.
Actually I just realized we have a "Writing generators" guide: https://github.com/ash-project/igniter/blob/main/documentation/writing-generators.md
Maybe lets merge these with the name "Writing installers and generators" 😄
I made a test before the guide to use an example I suppose. But before that we can improve the test also.
Contributor checklist